From 058248117f4b5cd2e1d66e6790799c5a7facdea1 Mon Sep 17 00:00:00 2001 From: Thisaru Guruge Date: Tue, 16 Apr 2024 14:14:33 +0530 Subject: [PATCH 1/3] Fix GraphQL BBE issues --- examples/graphql-dataloader/graphql_dataloader.bal | 2 +- examples/graphql-documentation/graphql_documentation.bal | 4 ++-- examples/graphql-documentation/graphql_documentation.md | 2 +- .../graphql_service_interceptors.bal | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/graphql-dataloader/graphql_dataloader.bal b/examples/graphql-dataloader/graphql_dataloader.bal index bbc8737fa4..80659bf61e 100644 --- a/examples/graphql-dataloader/graphql_dataloader.bal +++ b/examples/graphql-dataloader/graphql_dataloader.bal @@ -39,7 +39,7 @@ final readonly & table key(id) bookTable = table [ // of this function is an array of results in which each element in the result array corresponds // to a primary key from the `ids` array. isolated function bookLoaderFunction(readonly & anydata[] ids) returns BookRow[][]|error { - final readonly & int[] keys = check ids.ensureType(); + final int[] keys = check ids.ensureType(); log:printInfo("executing bookLoaderFunction", keys = keys); // Implement the batching logic. return keys.'map(isolated function(readonly & int key) returns BookRow[] { diff --git a/examples/graphql-documentation/graphql_documentation.bal b/examples/graphql-documentation/graphql_documentation.bal index ee1a6eb03e..f8888c911b 100644 --- a/examples/graphql-documentation/graphql_documentation.bal +++ b/examples/graphql-documentation/graphql_documentation.bal @@ -1,6 +1,6 @@ import ballerina/graphql; -// All the types that are used in the GraphQL service can have doc comments to add as documentation. +// All the types that are used in the GraphQL service can have documentation. # Represents a profile. # + name - The name of the profile # + age - The age of the profile @@ -11,7 +11,7 @@ type Profile record {| service /graphql on new graphql:Listener(9090) { - // Add doc comments to reflect them in the generated GraphQL schema. + // Add documentation to reflect them in the generated GraphQL schema. # Returns a profile using the provided ID. # + id - The ID of the profile # + return - The profile with the requested ID diff --git a/examples/graphql-documentation/graphql_documentation.md b/examples/graphql-documentation/graphql_documentation.md index 2b3a8bab03..722b8f3a53 100644 --- a/examples/graphql-documentation/graphql_documentation.md +++ b/examples/graphql-documentation/graphql_documentation.md @@ -1,6 +1,6 @@ # GraphQL service - Documentation -The Ballerina `graphql` module allows adding documentation to the `graphql:Service` and its subsequent types. To add documentation, use the Ballerina doc comments for the `graphql:Service`, `resource`/`remote` methods, types, and `enum`s. Add the documentation to include the descriptions to the generated GraphQL schema. +The Ballerina `graphql` module allows adding documentation to the generated GraphQL schema and its subsequent types. To add documentation, use the Ballerina documentation for the `graphql:Service`, `resource`/`remote` methods, types, and `enum`s. The Ballerina documentation will be automatically added as the documentation in the generated GraphQL schema. ::: code graphql_documentation.bal ::: diff --git a/examples/graphql-service-interceptors/graphql_service_interceptors.bal b/examples/graphql-service-interceptors/graphql_service_interceptors.bal index 07471cdb0f..803f3d565d 100644 --- a/examples/graphql-service-interceptors/graphql_service_interceptors.bal +++ b/examples/graphql-service-interceptors/graphql_service_interceptors.bal @@ -19,7 +19,7 @@ readonly service class LogInterceptor { log:printInfo(string `Field "${fieldName}" execution started!`); // The `context.resolve()` function can be used to invoke the next interceptor. If all the - // interceptors were executed, and it invokes the actual resolver function. The function + // interceptors were executed, then it invokes the actual resolver function. The function // returns an `anydata` type value that includes the execution result of the next // interceptor or the actual resolver. To call the `context.resolve()` function, the // `graphql:Field` value should be provided as the argument. From f85f3fe021c3b87b8a7cf591ebf108b732ce0730 Mon Sep 17 00:00:00 2001 From: Thisaru Guruge Date: Tue, 16 Apr 2024 15:57:28 +0530 Subject: [PATCH 2/3] Apply suggestions from code review --- .../graphql_subscriptions.bal | 34 ++++++++++++++----- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/examples/graphql-subscriptions/graphql_subscriptions.bal b/examples/graphql-subscriptions/graphql_subscriptions.bal index 173402ddad..efb10d7c05 100644 --- a/examples/graphql-subscriptions/graphql_subscriptions.bal +++ b/examples/graphql-subscriptions/graphql_subscriptions.bal @@ -1,13 +1,9 @@ import ballerina/graphql; +import ballerina/lang.runtime; +import ballerina/random; service /graphql on new graphql:Listener(9090) { - // Defines a `string` array in the service. - private string[] names; - - function init() { - // Initialize the array. - self.names = ["Walter White", "Jesse Pinkman", "Skyler White"]; - } + private final readonly & string[] names = ["Walter White", "Jesse Pinkman", "Saul Goodman"]; resource function get names() returns string[] { return self.names; @@ -16,7 +12,27 @@ service /graphql on new graphql:Listener(9090) { // A resource method with the `subscribe` accessor represents a field in the root // `Subscription` operation. It must always return a stream. Since the stream is of type // `string`, the resulting field in the generated GraphQL schema will be of type `String!`. - resource function subscribe names() returns stream { - return self.names.toStream(); + resource function subscribe names() returns stream { + NameGenerator nameGenerator = new (self.names); + stream names = new (nameGenerator); + return names; + } +} + +// Defines a StreamGenerator class that can be used to create a stream of strings. This will pick a random name from +// the list of names and return it with a delay to demonstrate a stream of values. +class NameGenerator { + private final string[] names; + + isolated function init(string[] names) { + self.names = names; + } + + // Function that picks a random name from the list and returns it. + public isolated function next() returns record {|string value;|}|error? { + // Sleep for 1 second to simulate a delay. + runtime:sleep(1); + int index = check random:createIntInRange(0, self.names.length()); + return {value: self.names[index]}; } } From 15993b0df9e3bd845fc742837a7f47ee7b3a485d Mon Sep 17 00:00:00 2001 From: Thisaru Guruge Date: Tue, 16 Apr 2024 15:57:28 +0530 Subject: [PATCH 3/3] Apply suggestions from code review --- examples/graphql-subscriptions/graphql_subscriptions.bal | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/examples/graphql-subscriptions/graphql_subscriptions.bal b/examples/graphql-subscriptions/graphql_subscriptions.bal index efb10d7c05..d070c0aca4 100644 --- a/examples/graphql-subscriptions/graphql_subscriptions.bal +++ b/examples/graphql-subscriptions/graphql_subscriptions.bal @@ -13,13 +13,15 @@ service /graphql on new graphql:Listener(9090) { // `Subscription` operation. It must always return a stream. Since the stream is of type // `string`, the resulting field in the generated GraphQL schema will be of type `String!`. resource function subscribe names() returns stream { + // Create a `NameGenerator` object. NameGenerator nameGenerator = new (self.names); + // Create a stream using the `NameGenerator` object. stream names = new (nameGenerator); return names; } } -// Defines a StreamGenerator class that can be used to create a stream of strings. This will pick a random name from +// Defines a stream implementor that can be used to create a stream of strings. This will pick a random name from // the list of names and return it with a delay to demonstrate a stream of values. class NameGenerator { private final string[] names; @@ -28,7 +30,7 @@ class NameGenerator { self.names = names; } - // Function that picks a random name from the list and returns it. + // The `next` method picks a random name from the list and returns it. public isolated function next() returns record {|string value;|}|error? { // Sleep for 1 second to simulate a delay. runtime:sleep(1);