GraphQL collides with Apache APIs IX to improve the security and performance in the API field

This paper introduces the characteristics of Apache apisid and GraphQL, and how to use Apache apisid, an API gateway, to proxy GraphQL requests, and puts forward a solution to the pain points of the actual scene.

background information

GraphQL is an open source, API oriented data query operation language and corresponding running environment. Originally developed internally by Facebook in 2012 and publicly released in 2015. On November 7, 2018, Facebook transferred the GraphQL project to the newly established GraphQL foundation.

You can understand GraphQL by analogy with SQL query statements. Compared with SQL query statements, GraphQL provides an easy to understand and complete description of the data in the API, so that the client can accurately obtain the data it needs through the customized description. This also allows the API to calmly face the development of increasingly complex interfaces and avoid eventually becoming a daunting complex interface.

As a cloud native gateway, Apache apisid has the ability to recognize the matching of GraphQL syntax at the beginning of its design. By efficiently matching the GraphQL statements carried in the request, abnormal traffic is filtered out to further ensure security and improve system performance.

Scene analysis

We are in the era of big data and large traffic. Apache apisid and GraphQL can form a win-win situation by combining. Next, give a specific description of the scene.

This article will discuss the practical application of Apache APIs IX and GraphQL in the microservice architecture scenario.

Problems encountered in the actual scene

In the later stage of the project, there are often problems of business complexity and high team mobility, and microservice architecture has become a common solution to these problems. In the microservice architecture, the interfaces exposed by GraphQL are divided into decentralized and centralized. However, only the centralized interface design can maximize the advantages of GraphQL. However, in the centralized interface design, all microservices expose the same interface. Therefore, the routing of processing traffic cannot be simply forwarded according to the URL, Instead, it should be forwarded according to the different fields contained in the request.

Because NGINX only processes the URL and some parameters when processing the request, but only by analyzing the query information in the request parameters can we know the resources accessed by the client, so as to carry out routing forwarding. Therefore, this routing forwarding method cannot be completed through traditional NGINX. In the actual application scenario, it is very dangerous to directly expose the GraphQL interface, so a professional high-performance API gateway is needed to protect the GraphQL interface.

Solution

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

Pasting block s outside Docs is not supported

In this scheme, Apache APIs IX is deployed before GraphQL Server as an API gateway to provide security for the whole back-end system. According to its GraphQL matching function, Apache APIs IX filters some requests and then processed by GraphQL Server, making the whole resource request process more efficient.

Thanks to the dynamic characteristics of Apache apisid, you can enable plug-ins such as current limit and speed limit, identity authentication and observability without restarting the service, so as to further improve the operation efficiency of this scheme and facilitate operation and maintenance.

In addition, Apache APIs IX can also target different graphqls_ Operation performs different permission verification for different graphql_name is forwarded to different Upstream. The details will be described below.

To sum up, the solution of Apache APIs IX + GraphQL not only makes full use of GraphQL's search advantages, but also has the security and stability of Apache APIs IX as an API gateway.

Application of GraphQL in Apache APIs IX

Basic logic

Pasting block s outside Docs is not supported

At present, the execution logic of GraphQL in Apache APIs IX is as follows:

  1. Clients send a request with GraphQL statement to Apache apisid;
  2. Apache APISIX matches the route and extracts the preset GraphQL data;
  3. Apache apisik matches the requested data through preset GraphQL data;

    1. If the match is successful, Apache apisid will continue to forward the request;
    2. If the match fails, Apache apisid will terminate the request immediately.
  4. Whether there are plug-ins;

    1. If there is a plug-in, the request will continue to be processed by the plug-in. After processing, it will continue to be forwarded to GraphQL Server;
    2. If the plug-in does not exist, the request is forwarded directly to the GraphQL Server.

In the internal matching in APISIX core, Apache APISIX supports GraphQL through GraphQL Lua library. Apache APIs IX GraphQL parsing library will first parse the request with GraphQL syntax, and then match the parsed request with the configuration data preset in Apache APIs IX database. If the match is successful, Apache apisid will release and forward the request, otherwise terminate the request.

Specific configuration

Apache APIs IX currently supports filtering routes through some attributes of GraphQL:

  • graphql_operation
  • graphql_name
  • graphql_root_fields

The properties of GraphQL correspond to the GraphQL query statement shown below one by one:

query getRepo {
    owner {
        name
    }
    repo {
        created
    }
}
  • graphql_ query corresponding to operation
  • graphql_name corresponds to getRepo
  • graphql_root_fields corresponds to ["owner", "repo"]

You can set up a path for Apache apifix to verify the matching ability of GraphQL through the following example:

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
        }
    }
}'

Next, use the request with GraphQL statement to access:

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

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

HTTP/1.1 200 OK

Otherwise, the request is terminated.

HTTP/1.1 404 Not Found

Advanced operation

Apache APIs IX can use different graphqls_ Name forwards to different Upstream, and according to different graphql_operation performs different permission checks. The code configuration for this feature is shown below.

Using graphql_name matches Upstream

  1. Create the first upstream service:
curl http://192.168.1.200:9080/apisix/admin/upstreams/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
    "type": "chash",
    "key": "remote_addr",
    "nodes": {
        "192.168.1.200:1980": 1
    }
}'   
  1. Create a GraphQL route bound to the first upstream service, GraphQL_ Set name to getRepo111:
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"
}'   
  1. Create a second upstream service:
curl http://192.168.1.200:9080/apisix/admin/upstreams/2 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
    "type": "chash",
    "key": "remote_addr",
    "nodes": {
        "192.168.1.200:1981": 1
    }
}'
  1. Create a GraphQL route bound to the second upstream service, GraphQL_ Set name to getRepo222:
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
}'
  1. Test example

Use the two graphqls you created earlier_ Test the name service, and you can find that Apache apisid can use different graphqls in the request_ Name automatically selects the Upstream to forward.

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

The response from the upstream 192.168.1.200:1980 will be returned:

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

The response from upstream 192.168.1.200:1981 will be returned:

HTTP/1.1 200 OK
---URI
/graphql
---Service Node
Centos-port: 1981

Using graphql_operation performs different permission checks

The above example provides graphql_operation is the matching rule of query. Now use GraphQL request in the form of mutation.

  1. To configure Apache APIs IX:
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"
    }
}'
  1. Initiate a mutation request to verify the configuration of Apache APIs IX:
curl -i -H 'content-type: application/graphql' -X POST http://192.168.1.200:9080/hello -d '
mutation repo($ep: Episode!, $review: ReviewInput!) {
  createReview(episode: $ep, review: $review) {
    stars
    commentary
  }
}'

The returned results are as follows:

HTTP/1.1 200 OK
---URI
/hello
---Service Node
Centos-port: 1982

Matching plug-ins

Apache APISIX has a rich plug-in ecosystem to apply different usage scenarios. If you add appropriate plug-ins when using Apache APISIX + GraphQL, you can make more scenarios for the application of the scheme.

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

Limit count speed plug-in

With the limit count plug-in, the traffic is further restricted after being forwarded through GraphQL matching rules. Thanks to the characteristics of Apache apisid, it can achieve dynamic, refined and distributed current and speed limit. For details, please refer to Apache APIs IX official documentation.

Observability plug-in

Apache APISIX provides observable plug-ins including but not limited to prometheus, skywalking and so on, which can provide more monitoring index data for the system and facilitate the subsequent operation and maintenance of the system.

summary

This article gives you a preliminary introduction to the application of GraphQL in Apache APIs IX, and uses the actual code to show you the combination of Apache APIs IX and GraphQL. Users can use GraphQL in Apache APIs IX according to their own business needs and actual scenarios.

For more description and complete configuration information of GraphQL, please refer to Official documents.

The Apache apisik project is currently developing other plug-ins to support the integration of more services. If you are interested, you can GitHub Discussions Initiate discussion or adopt mailing list Communicate.

Keywords: gateway graphql apisix

Added by Fed51 on Tue, 08 Mar 2022 05:10:14 +0200