This article introduces the features of Apache APISIX and GraphQL, how to use the API gateway Apache APISIX to proxy GraphQL request, and proposes a solution to the pain points in real scenarios.

Background information

GraphQL is an open source, API-oriented data query operation language and the corresponding runtime environment. Originally developed internally by Facebook in 2012, it was released publicly in 2015. On November 7, 2018, Facebook transferred the GraphQL project to the newly formed GraphQL Foundation.

You can think of GraphQL as a SQL query statement. Compared to SQL queries, GraphQL provides a complete and easy-to-understand description of the data in the API, allowing clients to customize the description to get exactly what they need. This also allows the API to cope with the growing complexity of the interface without ending up as a daunting one.

Apache APISIX, as a cloud native gateway, has the matching ability to recognize GraphQL syntax from the beginning of its design. Through efficient matching of GraphQL statements carried in the request, abnormal traffic is screened out to further ensure security and improve system performance.

Scenario analysis

We are in the era of big data and big traffic. Apache APISIX and GraphQL can be combined to create a win-win situation. Here’s a scenario to illustrate.

This article will discuss the practical application of Apache APISIX and GraphQL in microservices architecture scenarios.

Problems encountered in actual scenarios

Microservices architecture has become a common solution to the late-stage problems of business complexity and high team mobility. In microservice architecture, GraphQL exposes two kinds of interfaces: decentralized and centralized. However, only centralized interface design can maximize GraphQL’s advantages. However, in centralized interface design, all microservices are exposed to the same interface. Therefore, routing to handle traffic cannot simply forward based on the URL, but should forward based on the different fields contained in the request.

NGINX only processes URLS and some parameters when processing requests. However, only the query information in the request parameters can be parsed to know the resources accessed by the client, so as to carry out route forwarding. Therefore, this route forwarding mode cannot be completed by traditional NGINX. In a real-world application scenario, exposing the GraphQL interface directly is dangerous, so a professional high-performance API gateway is needed to protect the GraphQL interface.

The solution

Based on the security, stability and high performance of Apache APISIX, adding GraphQL flexible routing matching rules is the best solution to solve the problem of GraphQL centralized interface design.

Pasting blocks outside Docs is not supported

In this scheme, Apache APISIX is deployed before GraphQL Server as an API gateway, providing security for the whole backend system. In addition, Apache APISIX has GraphQL matching functions according to its own. Some of the requests are filtered and processed by the GraphQL Server, making the whole request resource process more efficient.

Thanks to the dynamic features of Apache APISIX, you can enable plug-ins such as traffic limiting, identity authentication, and observability without restarting services, further improving the operation efficiency of the solution and facilitating O&M.

In addition, Apache APISIX can perform different permissions for different GraphQL_operation and forward different graphql_name to different upstreams, as described below.

The Apache APISIX** + GraphQL solution takes full advantage of GraphQL search while also providing Apache APISIX with the security and stability of an API gateway. **

Application of GraphQL in Apache APISIX

Basic logic

Pasting blocks outside Docs is not supported

The execution logic of GraphQL in Apache APISIX is as follows:

  1. Clients initiates a request to Apache APISIX with a GraphQL statement;
  2. Apache APISIX matches the route and extracts the default GraphQL data;
  3. Apache APISIX matches the request data with preset GraphQL data;
    1. If the match is successful, Apache APISIX will continue forwarding the request.
    2. If the match fails, Apache APISIX will immediately terminate the request.
  4. Whether plug-ins exist;
    1. If there is a plug-in, the request will continue to be processed by the plug-in. After processing, the request will continue to be forwarded to the GraphQL Server.
    2. If no plug-in exists, the request is forwarded directly to GraphQL Server.

Apache APISIX implements graphQL support through the GraphQL-lua library for internal matching in APISIX core. The Apache APISIX GraphQL parsing library first parses the request with GraphQL syntax and then matches the parsed request with the configuration data preset in the Apache APISIX database. If the match is successful, Apache APISIX clears and forwards the request, otherwise it terminates the request.

Specific configuration

Apache APISIX currently supports routing filtering via GraphQL attributes:

  • graphql_operation

  • graphql_name

  • graphql_root_fields

The GraphQL properties correspond to the GraphQL query statement shown below:

query getRepo {
    owner {
        name
    }
    repo {
        created}}Copy the code
  • The corresponding query graphql_operation

  • The corresponding getRepo graphql_name

  • Graphql_root_fields corresponds to [“owner”, “repo”]

You can set up a path for Apache APISIX to verify its ability to match GraphQL using the following example:

The curl http://127.0.0.1:9080/apisix/admin/routes/1 - H 'X - API - KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -i -d ' { "methods": ["POST"], "uri": "/_graphql", "vars": [ ["graphql_operation", "==", "query"], ["graphql_name", "==", "getRepo"], ["graphql_root_fields", "has", "owner"] ], "Upstream" : {" type ":" roundrobin ", "nodes" : {" 192.168.1.200:4000 ": 1}}} 'Copy the code

Next use a request with a GraphQL statement to access:

curl -H 'content-type: Application/graphql 'POST http://127.0.0.1:9080/graphql - d - X' query getRepo {owner repo {name} {created}} 'Copy the code

If the match is successful, Apache APISIX continues to forward the request.

HTTP/1.1 200 OK
Copy the code

Otherwise, the request is terminated.

HTTP/1.1 404 Not Found
Copy the code

Advanced operation

Apache APISIX can forward to different upstreams based on different GraphQL_NAME and perform different permissions based on different GraphQL_operation. The code configuration for this feature is shown below.

usegraphql_nameMatch the Upstream

  1. Create the first upstream service:
The curl http://192.168.1.200:9080/apisix/admin/upstreams/1 - H 'X - API - KEY: Edd1c9f034335f136f87ad84b625c8f1 '- PUT X - d' {" type ":" chash ", "key" : "remote_addr", "nodes" : {" 192.168.1.200:1980 ": 1}} 'Copy the code
  1. Create a GraphQL route to bind to the first upstream service,graphql_nameSet togetRepo111:
The curl http://192.168.1.200:9080/apisix/admin/routes/1 - H 'X - API - KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -i -d ' { "methods": ["POST"], "uri": "/graphql", "vars": [ ["graphql_operation", "==", "query"], ["graphql_name", "==", "getRepo111"], ["graphql_root_fields", "has", "owner"] ], "upstream_id": "1" }'Copy the code
  1. Create a second upstream service:
The curl http://192.168.1.200:9080/apisix/admin/upstreams/2 - H 'X - API - KEY: Edd1c9f034335f136f87ad84b625c8f1 '- PUT X - d' {" type ":" chash ", "key" : "remote_addr", "nodes" : {" 192.168.1.200:1981 ": 1}} 'Copy the code
  1. Create a GraphQL route to bind to the second upstream service,graphql_nameSet togetRepo222:
The curl http://192.168.1.200:9080/apisix/admin/routes/2 - H 'X - API - KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -i -d ' { "methods": ["POST"], "uri": "/graphql", "vars": [ ["graphql_operation", "==", "query"], ["graphql_name", "==", "getRepo222"], ["graphql_root_fields", "has", "owner"] ], "upstream_id": 2 }'Copy the code
  1. Test the sample

Using the two GraphQL_name services you created earlier, you can see that Apache APISIX can automatically select Upstream to forward based on the different GraphQL_name in the request.

  1. If the request is this example:
curl -i -H 'content-type: Application/graphql 'POST http://192.168.1.200:9080/graphql - d - X' query getRepo111 {owner repo {name} {created} } 'Copy the code

The response from upstream 192.168.1.200:1980 is returned:

HTTP/1.1 200 OK --URI/graphQL --Service Node centos-port: 1980Copy the code
  1. If the request is this example:
curl -i -H 'content-type: Application/graphql 'POST http://192.168.1.200:9080/graphql - d - X' query getRepo222 {owner repo {name} {created} } 'Copy the code

A response from upstream 192.168.1.200:1981 is returned:

HTTP/1.1 200 OK --URI/graphQL --Service Node centos-port: 1981Copy the code

usegraphql_operationVerify different permissions

The example above provided a matching rule for graphQL_operation as query, and now uses the GraphQL request in the form of mutation.

  1. Configure Apache APISIX:
The curl http://192.168.1.200:9080/apisix/admin/routes/11 - H 'X - API - KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d ' { "methods": ["POST"], "uri": "/hello", "vars": [ ["graphql_operation", "==", "mutation"], ["graphql_name", "==", "repo"] ], "upstream": { "nodes": {" 192.168.1.200:1982 ": 1}," type ":" roundrobin "}} 'Copy the code
  1. initiatemutationRequest to verify the configuration of Apache APISIX:
Curl - I - H 'the content-type: application/graphql - X POST http://192.168.1.200:9080/hello - d' mutation '($ep: Episode came! , $review: ReviewInput!) { createReview(episode: $ep, review: $review) { stars commentary } }'Copy the code

The result is as follows:

HTTP/1.1 200 OK --URI /hello --Service Node centos-port: 1982Copy the code

Match the plug-in

Apache APISIX has a rich plug-in ecosystem to apply different usage scenarios, and if you add the appropriate plug-ins to use Apache APISIX + GraphQL, you can make the scenario apply more scenarios.

This article only selects the following two types of plug-ins for example.

limit-countSpeed plug-in

With limit-count, traffic is further restricted after being forwarded by GraphQL matching rules. Thanks to the features of Apache APISIX, it can achieve dynamic, refined and distributed traffic limiting and speed limiting. For details, see the Apache APISIX official documentation.

Observability plug-in

Apache APISIX provides observable plug-ins, including but not limited to Prometheus and Skywalking, to provide more monitoring indicator data for system operation and maintenance.

conclusion

This article introduces the application of GraphQL in Apache APISIX and shows the combination of Apache APISIX and GraphQL using actual code. Users can use GraphQL in Apache APISIX based on their business needs and actual scenarios.

For more instructions and complete configuration information on GraphQL, see the official documentation.

The Apache APISIX project is currently developing additional plug-ins to support the integration of additional services, and if you are interested, you can initiate a discussion through GitHub Discussions, or communicate via the mailing list.