Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Context Support for GraphQL Resolvers #417

Merged
merged 18 commits into from
Sep 24, 2021
Merged

Add Context Support for GraphQL Resolvers #417

merged 18 commits into from
Sep 24, 2021

Conversation

ThisaruGuruge
Copy link
Member

Purpose

Add GraphQL context support that can be used to share metadata between the resolvers.

Fixes: #1906
Fixes: #1953

Examples

Developers can provide a function to initialize the context which must be an isolated function, and must have two input parameters: http:Request and http:RequestContext. This function must have the return type of graphql:Context|error.

Inside this function, the graphql:Context object can be created and the developer can add attributes to the context as key-value pairs. The key is always a string, the value can be a value:Clonable|isolated object {}. Simply put, this can be a primitive value, any readonly value, or an isolated function pointer, or an isolated object. The context object has three functions, add, get, and remove.
Then this function can be provided as a service config field. Using this function, a context will be created per request. When needed, the context can be defined as the first parameter of a resolver (resource/remote) function. Following is an example:

import ballerina/graphql;
import ballerina/http;

isolated function initContext(http:Request request, http:RequestContext requestContext) returns graphql:Context|error {
    graphql:Context context = new;
    check context.add("scope", request.getHeader("scope"));
    return context;
}

@graphql:ServiceConfig {
    contextInit: initContext
} 
service on new graphql:Listener(9000) {
    resource function get greting(graphql:Context context) returns string {
        if context.get("scope") is string && context.get("scope") == "admin" {
            return "Hello, admin!";
        } else {
            return "Hello, user!";
        }
    }
}

Checklist

  • Linked to an issue
  • Updated the changelog
  • Added tests

@codecov
Copy link

codecov bot commented Sep 23, 2021

Codecov Report

Merging #417 (393d4a8) into master (d2908bc) will decrease coverage by 0.21%.
The diff coverage is 86.31%.

Impacted file tree graph

@@             Coverage Diff              @@
##             master     #417      +/-   ##
============================================
- Coverage     94.84%   94.63%   -0.22%     
- Complexity      278      285       +7     
============================================
  Files            49       50       +1     
  Lines          2912     2983      +71     
  Branches       1347     1390      +43     
============================================
+ Hits           2762     2823      +61     
- Misses          132      138       +6     
- Partials         18       22       +4     
Impacted Files Coverage Δ
...rina/stdlib/graphql/runtime/schema/TypeFinder.java 96.03% <0.00%> (ø)
.../ballerina/stdlib/graphql/runtime/utils/Utils.java 70.58% <33.33%> (-20.33%) ⬇️
...allerina/stdlib/graphql/runtime/engine/Engine.java 92.62% <71.42%> (-0.60%) ⬇️
ballerina/http_service.bal 88.88% <89.28%> (-11.12%) ⬇️
ballerina/context.bal 93.10% <93.10%> (ø)
ballerina/annotation_processor.bal 100.00% <100.00%> (ø)
ballerina/annotations.bal 100.00% <100.00%> (ø)
ballerina/engine.bal 97.01% <100.00%> (+1.24%) ⬆️
ballerina/executor_visitor.bal 91.83% <100.00%> (+0.17%) ⬆️
ballerina/listener.bal 80.48% <100.00%> (+0.48%) ⬆️
... and 6 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update d2908bc...393d4a8. Read the comment docs.

@ThisaruGuruge ThisaruGuruge changed the title Add context Add Context Support for GraphQL Resolvers Sep 24, 2021
public type GraphqlServiceConfig record {|
int maxQueryDepth?;
ListenerAuthConfig[] auth?;
ContextInit contextInit?;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if we assign a default value for this ? Something like

isolated function initDefaultContext(http:Request request, http:RequestContext requestContext) returns graphql:Context|error {
    return graphql:Context();
}

That way it is explicit that we create a default one if nothing is given.

Copy link
Member Author

@ThisaruGuruge ThisaruGuruge Sep 24, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We already have a function for this:

isolated function initContext(http:Request request, http:RequestContext requestContext) returns Context|error {

I'll rename this as initDefaultContext

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ThisaruGuruge @shafreenAnfar What do you think about the field name contextInit? I prefer this to be as Context context, and passing a function pointer which creates a Context for me. But I understand that it is not possible with Ballerina way of handling types. So, what do you think of having this as ContextInit context?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At first, I went through the same thought process. But then went with contextInit because this isn't actually a context, but a function that initializes a context.
IMHO, this makes it easy for the developers to understand what it is. They have to provide a ContextInit (which is a function pointer), not a Context (which is an object).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah. Agree with the clarification.

@shafreenAnfar shafreenAnfar merged commit fa49f63 into master Sep 24, 2021
@ThisaruGuruge ThisaruGuruge deleted the add-context branch September 24, 2021 10:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

GraphQL Record Fields Allow Invalid Types [GraphQL] Context support is needed for graphQL library
3 participants