-
Notifications
You must be signed in to change notification settings - Fork 192
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #5530 from ThisaruGuruge/graphql-query-complexity
Add GraphQL Query Complexity BBE
- Loading branch information
Showing
10 changed files
with
117 additions
and
1 deletion.
There are no files selected for viewing
6 changes: 6 additions & 0 deletions
6
examples/graphql-service-query-complexity/graphql_service_query_complexity.1.graphql
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
query { | ||
profile(id: 1) { | ||
name | ||
age | ||
} | ||
} |
9 changes: 9 additions & 0 deletions
9
examples/graphql-service-query-complexity/graphql_service_query_complexity.2.graphql
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
query { | ||
profile1: profile(id: 1) { | ||
name | ||
age | ||
} | ||
profile2: profile(id: 2) { | ||
age | ||
} | ||
} |
51 changes: 51 additions & 0 deletions
51
examples/graphql-service-query-complexity/graphql_service_query_complexity.bal
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import ballerina/graphql; | ||
|
||
// Defines a service class to use as an object in the GraphQL service. | ||
service class Profile { | ||
private final string name; | ||
private final int age; | ||
|
||
function init(string name, int age) { | ||
self.name = name; | ||
self.age = age; | ||
} | ||
|
||
@graphql:ResourceConfig { | ||
complexity: 1 | ||
} | ||
resource function get name() returns string { | ||
return self.name; | ||
} | ||
|
||
@graphql:ResourceConfig { | ||
complexity: 10 | ||
} | ||
resource function get age() returns int { | ||
return self.age; | ||
} | ||
|
||
// Default complexity will be applied | ||
resource function get isAdult() returns boolean { | ||
return self.age > 21; | ||
} | ||
} | ||
|
||
@graphql:ServiceConfig { | ||
// The queryComplexityConfig is used to define the values for the maximum query complexity, | ||
// default field complexity, and whether to return an error or warning when the maximum | ||
// complexity is exceeded. | ||
queryComplexityConfig: { | ||
maxComplexity: 50, // Maximum complexity allowed for a query | ||
defaultFieldComplexity: 2 // Default complexity for a field | ||
} | ||
} | ||
service graphql:Service /graphql on new graphql:Listener(9090) { | ||
|
||
@graphql:ResourceConfig { | ||
complexity: 20 // Assigning a complexity value to the `profile` field | ||
} | ||
resource function get profile(@graphql:ID int id) returns Profile { | ||
// Return a dummy profile object | ||
return new ("Walter White", 50); | ||
} | ||
} |
2 changes: 2 additions & 0 deletions
2
examples/graphql-service-query-complexity/graphql_service_query_complexity.client.1.out
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
$ curl -X POST -H "Content-type: application/json" -H "scope: admin" -d '{ "query": "{ profile(id: 1) { name age } }" }' 'http://localhost:9090/graphql' | ||
{"data":{"profile":{"name":"Walter White", "age":50}}} |
2 changes: 2 additions & 0 deletions
2
examples/graphql-service-query-complexity/graphql_service_query_complexity.client.2.out
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
curl -X POST -H "Content-type: application/json" -H "scope: admin" -d '{ "query": "{ profile1: profile(id: 1) { name age } profile2: profile(id: 2) { name age } }" }' 'http://localhost:9090/graphql' | ||
{"errors":[{"message":"The operation exceeds the maximum query complexity threshold. Maximum allowed complexity: 50, actual complexity: 62", "locations":[{"line":1, "column":1}]}]} |
35 changes: 35 additions & 0 deletions
35
examples/graphql-service-query-complexity/graphql_service_query_complexity.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
# GraphQL service - Query Complexity | ||
|
||
a `graphql:Service` can be secured by limiting the complexity of the operations that can be executed. This can be done by setting a maximum complexity threshold for a given service. The query complexity is calculated by assigning a complexity value to each field in the GraphQL schema. The complexity of an operation is the sum of the complexity values of the fields in the operation. | ||
|
||
::: code graphql_service_query_complexity.bal ::: | ||
|
||
Run the service by executing the command below. | ||
|
||
::: out graphql_service_query_complexity.server.out ::: | ||
|
||
Send the following document to the GraphQL endpoint to test the service. | ||
|
||
::: code graphql_service_query_complexity.1.graphql ::: | ||
|
||
To send the document, execute the following cURL command in a separate terminal. | ||
|
||
::: out graphql_service_query_complexity.client.1.out ::: | ||
|
||
As shown in the output above, the query is executed without any issues. Now, send the following document to the GraphQL endpoint. | ||
|
||
::: code graphql_service_query_complexity.2.graphql ::: | ||
|
||
To send the document, execute the following cURL command in a separate terminal. | ||
|
||
::: out graphql_service_query_complexity.client.2.out ::: | ||
|
||
This will result in an error as the query complexity exceeds the maximum complexity threshold set for the service. | ||
|
||
>**Tip:** You can invoke the above service via the [GraphQL client](/learn/by-example/graphql-client-query-endpoint/). | ||
## Related links | ||
|
||
- [`graphql:ServiceConfig` record - API documentation](https://lib.ballerina.io/ballerina/graphql/latest#ServiceConfig) | ||
- [GraphQL `queryComplexityConfiguration` - Specification](/spec/graphql/#7110-query-complexity-configurations) | ||
- [GraphQL query complexity validation - Specification](/spec/graphql/#1091-query-complexity-validation) |
2 changes: 2 additions & 0 deletions
2
examples/graphql-service-query-complexity/graphql_service_query_complexity.metatags
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
description: This example demonstrates securing a GraphQL service query complexity analysis. | ||
keywords: ballerina, ballerina by example, bbe, graphql, service, security, query complexity |
1 change: 1 addition & 0 deletions
1
examples/graphql-service-query-complexity/graphql_service_query_complexity.server.out
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
$ bal run graphql_service_query_complexity.bal |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters