apache / apisix

The Cloud-Native API Gateway
https://apisix.apache.org/blog/
Apache License 2.0
14.45k stars 2.51k forks source link

bug: failed to parse graphql #10346

Open GuoMonth opened 1 year ago

GuoMonth commented 1 year ago

Current Behavior

this my request

 public async Task<PageData<ClientInfoData>> RetrieveByPage(int index, int size)
        {
            GraphQLRequest fetchQuery = new()
            {
                Query = @"query tClientInfo($pageSize: Int!, $pageIndex: Int!) {
    tClientInfo(
        filters: { status: { eq: 1 } }
        pagination: { page: { limit: $pageSize, page: $pageIndex } }
        orderBy: { updateTime: DESC }
    ) {
        nodes {
            id
            clientId
            clientCode
            clientName
            status
            createUser
            createTime
            remark
            updateTime
            updateUser
        }
        paginationInfo {
            pages
            current
        }
    }
}",
                Variables = new
                {
                    pageSize = size,
                    pageIndex = index,
                },
            };

            var token = await this.LocalStorage.GetItemAsync<string>("Token");
            this.GraphqlHttp.HttpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
            var fetchResJson = await this.GraphqlHttp.SendQueryAsync<JsonDocument>(fetchQuery);
 // ....
}

Expected Behavior

get a respond

Error Logs

2023/10/17 00:55:32 [error] 50#50: *577068048 [lua] ctx.lua:138: get_parsed_graphql(): failed to parse graphql: Syntax error near line 1 body: {"query":"query tClientInfo($pageSize: Int!, $pageIndex: Int!) {\n    tClientInfo(\n        filters: { status: { eq: 1 } }\n        pagination: { page: { limit: $pageSize, page: $pageIndex } }\n        orderBy: { updateTime: DESC }\n    ) {\n        nodes {\n            id\n            clientId\n            clientCode\n            clientName\n            status\n            createUser\n            createTime\n            remark\n            updateTime\n            updateUser\n        }\n        paginationInfo {\n            pages\n            current\n        }\n    }\n}\n","variables":{"pageSize":15,"pageIndex":0}}, client: 172.17.0.15, server: _, request: "POST /client/graphql HTTP/1.1"

Steps to Reproduce

  1. Run APISIX in k8s
  2. config route
  3. use C# GraphQL.Client.Http.GraphQLHttpClient request.

the route config info:

apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
  name: fx-client-route
spec:
  http:
  - name: fx-client-rule-1
    match:
      paths:
      - /client/save/*
      - /client/find_client_info_by_page
    backends: 
      - serviceName: fx-service-client-service
        servicePort: 8007
    plugins:
      - name: jwt-auth
        enable: true
      - name: cors
        enable: true
  - name: fx-client-rule-2
    match:
      methods: ["GET"]
      paths:
      - /client/hi
      - /client/graphql
    backends: 
      - serviceName: fx-service-client-service
        servicePort: 8007
    plugins:
      - name: cors
        enable: true
  - name: fx-client-rule-3
    match:
      methods: ["POST"]
      paths:
      - /client/graphql
      exprs:
      - subject:
          scope: Variable
          name: graphql_operation
        op: Equal
        value: query
    backends: 
      - serviceName: fx-service-client-service
        servicePort: 8007
    plugins:
      - name: jwt-auth
        enable: true
      - name: cors
        enable: true

Environment

GuoMonth commented 1 year ago

in my local, without APISIX, direct request GraphQL Servier is success.

kayx23 commented 1 year ago

You mean direct request from your C# app to GraphQL Server without APISIX sitting in the middle works alright?

GuoMonth commented 1 year ago

Yes

kayx23 commented 1 year ago

@Revolyssup please take a look

Revolyssup commented 1 year ago

@GuoMonth Can you add the "GET" method here as well?

      methods: ["POST","GET"]
      paths:
      - /client/graphql
kayx23 commented 1 year ago

Not sure if adding GET helps as the config has exprs below to match requests. Does it work if you remove the exprs?

      exprs:
      - subject:
          scope: Variable
          name: graphql_operation
        op: Equal
        value: query

Also I don't see Variable as an acceptable value for the scope in the doc. Please double check.

Additionally this may be relevant https://github.com/apache/apisix-ingress-controller/issues/1223

GuoMonth commented 1 year ago

I am do some test, this is result:

  1. nothing change, just use postman request, success.
  2. remove the exprs, postman and C# app request all success.
GuoMonth commented 1 year ago

do nothing change(with the exprs), I am use curl request , success.

curl --location 'http://x.x.x.x:xxx/client/graphql' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer xxxxciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2OTc2NzgyOTAsImtleSI6InVzZXIta2V5In0.uwbJBHgSRwKRSPloqq9uqeiXHmK9OhsXaPXFnlW19wI' \
--data '{"query":"query tClientInfo($pageSize: Int!, $pageIndex: Int!) {\n    tClientInfo(\n        filters: { status: { eq: 1 } }\n        pagination: { page: { limit: $pageSize, page: $pageIndex } }\n        orderBy: { updateTime: DESC }\n    ) {\n        nodes {\n            id\n            clientId\n            clientCode\n            clientName\n            status\n            createUser\n            createTime\n            remark\n            updateTime\n            updateUser\n        }\n        paginationInfo {\n            pages\n            current\n        }\n    }\n}","variables":{"pageSize":10,"pageIndex":1}}'

response

{
    "data": {
        "tClientInfo": {
            "nodes": [],
            "paginationInfo": {
                "pages": 1,
                "current": 1
            }
        }
    }
}
GuoMonth commented 1 year ago

It's really incomprehensible!

I compare graphql request strings from C# app and cURL, No difference found. and compare graphql request strings from cURL and error log , No difference found.

String mystery... 💔

kayx23 commented 1 year ago

do nothing change(with the exprs), I am use curl request , success.

curl --location 'http://x.x.x.x:xxx/client/graphql' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer xxxxciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2OTc2NzgyOTAsImtleSI6InVzZXIta2V5In0.uwbJBHgSRwKRSPloqq9uqeiXHmK9OhsXaPXFnlW19wI' \
--data '{"query":"query tClientInfo($pageSize: Int!, $pageIndex: Int!) {\n    tClientInfo(\n        filters: { status: { eq: 1 } }\n        pagination: { page: { limit: $pageSize, page: $pageIndex } }\n        orderBy: { updateTime: DESC }\n    ) {\n        nodes {\n            id\n            clientId\n            clientCode\n            clientName\n            status\n            createUser\n            createTime\n            remark\n            updateTime\n            updateUser\n        }\n        paginationInfo {\n            pages\n            current\n        }\n    }\n}","variables":{"pageSize":10,"pageIndex":1}}'

response

{
    "data": {
        "tClientInfo": {
            "nodes": [],
            "paginationInfo": {
                "pages": 1,
                "current": 1
            }
        }
    }
}

Is this sent to APISIX? What if you send one to APISIX this way:

image

screenshot from this blog.

Revolyssup commented 12 months ago

@GuoMonth Any updates?

GuoMonth commented 12 months ago

I will try something today.

GuoMonth commented 12 months ago

Test Case 1

  1. web wasm client: .net 7 App, Include="GraphQL.Client" Version="6.0.0".
  2. graphql service: rust 1.73, k8s deploy.
    async-graphql = { version = "5.0.10", default-features = false }
    async-graphql-axum = "5.0.10"
    sea-orm = { version = "0.12", default-features = false}
    seaography = {version = "^1.0.0-rc.2", default-features = false}

config the apisix route

~> kubectl apply -n xxxx-services  -f /Users/guosheng/AzureDevOps/fx-service-client/apisix-test.yaml
apisixroute.apisix.apache.org/fx-client-route created
~>kubectl describe ApisixRoute -n xxxx-services fx-client-route
Name:         fx-client-route
Namespace:    xxxx-services
Labels:       <none>
Annotations:  <none>
API Version:  apisix.apache.org/v2
Kind:         ApisixRoute
Metadata:
  Creation Timestamp:  2023-10-26T02:10:29Z
  Generation:          1
  Resource Version:    27913024655
  Self Link:           /apis/apisix.apache.org/v2/namespaces/xxxx-services/apisixroutes/fx-client-route
  UID:                 b75529cd-ed8c-4036-xxxx-3660775fxxxx
Spec:
  Http:
    Backends:
      Service Name:  xxxx-fx-service-client-service
      Service Port:  8007
    Match:
      Methods:
        POST
        GET
      Paths:
        /client/graphql
    Name:  fx-client-rule-graphql
    Plugins:
      Enable:  true
      Name:    jwt-auth
      Enable:  true
      Name:    cors
Status:
  Conditions:
    Message:              Sync Successfully
    Observed Generation:  1
    Reason:               ResourcesSynced
    Status:               True
    Type:                 ResourcesAvailable
Events:
  Type    Reason           Age              From           Message
  ----    ------           ----             ----           -------
  Normal  ResourcesSynced  6s (x2 over 6s)  ApisixIngress  ApisixIngress synced successfully

apisix-test.yaml

apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
  name: fx-client-route
spec:
  http:
    - name: fx-client-rule-graphql
      match:
        methods: ["POST", "GET"]
        paths:
          - /client/graphql
      backends:
        - serviceName: xxxx-fx-service-client-service
          servicePort: 8007
      plugins:
        - name: jwt-auth
          enable: true
        - name: cors
          enable: true

Test

1 cURL: success!

 ~> curl --location 'http://xx.xx.xx.xx:xx/client/graphql' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer xxxbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2OTgzNzI1MjcsImtleSI6InVzZXIta2V5In0.JN126xataNmTw7-PgxxxvCwYClRSttob-xxxCerlRs' \
--data '{"query":"query tClientInfo($pageSize: Int!, $pageIndex: Int!) {\n    tClientInfo(\n        filters: { status: { eq: 1 } }\n        pagination: { page: { limit: $pageSize, page: $pageIndex } }\n        orderBy: { updateTime: DESC }\n    ) {\n        nodes {\n            id\n            clientId\n            clientCode\n            clientName\n            status\n            createUser\n            createTime\n            remark\n            updateTime\n            updateUser\n        }\n        paginationInfo {\n            pages\n            current\n        }\n    }\n}\n","variables":{"pageSize":3,"pageIndex":1}}'

{"data":{"tClientInfo":{"nodes":[],"paginationInfo":{"pages":1,"current":1}}}}%

2 my .net 7 App, Include="GraphQL.Client" Version="6.0.0": success!

        public async Task<PageData<ClientInfoData>> RetrieveByPage(int index, int size)
        {
            GraphQLRequest fetchQuery = new()
            {
                Query = @"query tClientInfo($pageSize: Int!, $pageIndex: Int!) {
                    tClientInfo(
                        filters: { status: { eq: 1 } }
                        pagination: { page: { limit: $pageSize, page: $pageIndex } }
                        orderBy: { updateTime: DESC }
                    ) {
                        nodes {
                            id
                            clientId
                            clientCode
                            clientName
                            status
                            createUser
                            createTime
                            remark
                            updateTime
                            updateUser
                        }
                        paginationInfo {
                            pages
                            current
                        }
                    }
                }",
                Variables = new
                {
                    pageSize = size,
                    pageIndex = index,
                },
            };

            var token = await this.LocalStorage.GetItemAsync<string>("Token");
            this.GraphqlHttp.HttpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
            var fetchResJson = await this.GraphqlHttp.SendQueryAsync<JsonDocument>(fetchQuery);
            var fetchResData = fetchResJson.Data.RootElement.GetProperty("tClientInfo").GetProperty("nodes");
            var fetchResPaginationInfo = fetchResJson.Data.RootElement.GetProperty("tClientInfo").GetProperty("paginationInfo");

            var totalPages = fetchResPaginationInfo.GetProperty("pages").GetInt32();
            var data = fetchResData.Deserialize<List<ClientInfoData>>() ?? new List<ClientInfoData>();

            var clientInfoPage = new PageData<ClientInfoData>
            {
                Data = data,
                TotalPages = totalPages,
                PageIndex = index,
                PageSize = size,
                Total = totalPages * size, // note: this is not accurate, because graphql not respond 'total' info.
            };

            return clientInfoPage;
        }
GuoMonth commented 12 months ago

Test Case 2

  1. web wasm client: .net 7 App, Include="GraphQL.Client" Version="6.0.0".
  2. graphql service: rust 1.73, k8s deploy.
    async-graphql = { version = "5.0.10", default-features = false }
    async-graphql-axum = "5.0.10"
    sea-orm = { version = "0.12", default-features = false}
    seaography = {version = "^1.0.0-rc.2", default-features = false}

config the apisix route

~> kubectl apply -n xxxx-services  -f /Users/guosheng/AzureDevOps/fx-service-client/apisix-test.yaml
apisixroute.apisix.apache.org/fx-client-route configured

~> kubectl describe ApisixRoute -n xxxx-services fx-client-route
Name:         fx-client-route
Namespace:    xxxx-services
Labels:       <none>
Annotations:  <none>
API Version:  apisix.apache.org/v2
Kind:         ApisixRoute
Metadata:
  Creation Timestamp:  2023-10-26T02:10:29Z
  Generation:          2
  Resource Version:    27913423206
  Self Link:           /apis/apisix.apache.org/v2/namespaces/xxxx-services/apisixroutes/fx-client-route
  UID:                 b75529cd-ed8c-4036-b855-3xxxx75fc67f
Spec:
  Http:
    Backends:
      Service Name:  xxxx-fx-service-client-service
      Service Port:  8007
    Match:
      Exprs:
        Op:  Equal
        Subject:
          Name:   graphql_operation
          Scope:  Variable
        Value:    query
      Methods:
        POST
        GET
      Paths:
        /client/graphql
    Name:  fx-client-rule-graphql
    Plugins:
      Enable:  true
      Name:    jwt-auth
      Enable:  true
      Name:    cors
Status:
  Conditions:
    Message:              Sync Successfully
    Observed Generation:  2
    Reason:               ResourcesSynced
    Status:               True
    Type:                 ResourcesAvailable
Events:
  Type    Reason           Age                From           Message
  ----    ------           ----               ----           -------
  Normal  ResourcesSynced  11s (x4 over 18m)  ApisixIngress  ApisixIngress synced successfully

apisix-test.yaml

apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
  name: fx-client-route
spec:
  http:
    - name: fx-client-rule-graphql
      match:
        methods: ["POST", "GET"]
        paths:
          - /client/graphql
        exprs:
          - subject:
              scope: Variable
              name: graphql_operation
            op: Equal
            value: query
      backends:
        - serviceName: xxxx-fx-service-client-service
          servicePort: 8007
      plugins:
        - name: jwt-auth
          enable: true
        - name: cors
          enable: true

Test

1 cURL: success!

 ~> curl --location 'http://xx.xx.xx.xx:xxx/client/graphql' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer eyJhxxxx1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOxxxgzNzI1MjcsImtleSI6InVzZxxxn0.JN126xataNmTw7-Pgj34vCwYCxxxttob-l2FYCerlRs' \
--data '{"query":"query tClientInfo($pageSize: Int!, $pageIndex: Int!) {\n    tClientInfo(\n        filters: { status: { eq: 1 } }\n        pagination: { page: { limit: $pageSize, page: $pageIndex } }\n        orderBy: { updateTime: DESC }\n    ) {\n        nodes {\n            id\n            clientId\n            clientCode\n            clientName\n            status\n            createUser\n            createTime\n            remark\n            updateTime\n            updateUser\n        }\n        paginationInfo {\n            pages\n            current\n        }\n    }\n}\n","variables":{"pageSize":3,"pageIndex":1}}'

{"data":{"tClientInfo":{"nodes":[],"paginationInfo":{"pages":1,"current":1}}}}%

2 my .net 7 App, Include="GraphQL.Client" Version="6.0.0": failed!

        public async Task<PageData<ClientInfoData>> RetrieveByPage(int index, int size)
        {
            GraphQLRequest fetchQuery = new()
            {
                Query = @"query tClientInfo($pageSize: Int!, $pageIndex: Int!) {
                    tClientInfo(
                        filters: { status: { eq: 1 } }
                        pagination: { page: { limit: $pageSize, page: $pageIndex } }
                        orderBy: { updateTime: DESC }
                    ) {
                        nodes {
                            id
                            clientId
                            clientCode
                            clientName
                            status
                            createUser
                            createTime
                            remark
                            updateTime
                            updateUser
                        }
                        paginationInfo {
                            pages
                            current
                        }
                    }
                }",
                Variables = new
                {
                    pageSize = size,
                    pageIndex = index,
                },
            };

            var token = await this.LocalStorage.GetItemAsync<string>("Token");
            this.GraphqlHttp.HttpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
            var fetchResJson = await this.GraphqlHttp.SendQueryAsync<JsonDocument>(fetchQuery);
            var fetchResData = fetchResJson.Data.RootElement.GetProperty("tClientInfo").GetProperty("nodes");
            var fetchResPaginationInfo = fetchResJson.Data.RootElement.GetProperty("tClientInfo").GetProperty("paginationInfo");

            var totalPages = fetchResPaginationInfo.GetProperty("pages").GetInt32();
            var data = fetchResData.Deserialize<List<ClientInfoData>>() ?? new List<ClientInfoData>();

            var clientInfoPage = new PageData<ClientInfoData>
            {
                Data = data,
                TotalPages = totalPages,
                PageIndex = index,
                PageSize = size,
                Total = totalPages * size, // note: this is not accurate, because graphql not respond 'total' info.
            };

            return clientInfoPage;
        }

apisix error log:

172.17.0.6 - - [26/Oct/2023:02:34:07 +0000] xx.xx.xx.xx:xx "POST /client/graphql HTTP/1.1" 404 47 0.000 "http://localhost:5003/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36 Edg/118.0.2088.61" - - - "http://xx.xx.xx.xx:xx"
2023/10/26 02:34:59 [error] 52#52: *669067163 [lua] ctx.lua:138: get_parsed_graphql(): failed to parse graphql: Syntax error near line 1 body: {"query":"query tClientInfo($pageSize: Int!, $pageIndex: Int!) {\n                    tClientInfo(\n                        filters: { status: { eq: 1 } }\n                        pagination: { page: { limit: $pageSize, page: $pageIndex } }\n                        orderBy: { updateTime: DESC }\n                    ) {\n                        nodes {\n                            id\n                            clientId\n                            clientCode\n                            clientName\n                            status\n                            createUser\n                            createTime\n                            remark\n                            updateTime\n                            updateUser\n                        }\n                        paginationInfo {\n                            pages\n                            current\n                        }\n                    }\n                }","variables":{"pageSize":15,"pageIndex":0}}, client: 172.17.0.6, server: _, request: "POST /client/graphql HTTP/1.1", host: "xx.xx.xx.xx:xx", referrer: "http://localhost:5003/"

change .net graphql query code to this, till get error

GraphQLRequest fetchQuery = new()
            {
                Query = "query tClientInfo{\n tClientInfo(\n filters: { status: { eq: 1 } }\n pagination: { page: { limit: $pageSize, page: $pageIndex } }\n orderBy: { updateTime: DESC }\n ) {\n nodes {\n id\n clientId\n clientCode\n clientName\n status\n createUser\n createTime\n remark\n updateTime\n updateUser\n }\n paginationInfo {\n pages\n current\n }\n }\n }",
            };
172.17.0.15 - - [26/Oct/2023:02:43:01 +0000]  xx.xx.xx.xx: xx "POST /client/graphql HTTP/1.1" 404 47 0.000 "http://localhost:5003/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36 Edg/118.0.2088.61" - - - "http:// xx.xx.xx.xx: xx"
2023/10/26 02:44:39 [error] 51#51: *669141418 [lua] ctx.lua:138: get_parsed_graphql(): failed to parse graphql: Syntax error near line 1 body: {"query":"query tClientInfo{\n tClientInfo(\n filters: { status: { eq: 1 } }\n pagination: { page: { limit: $pageSize, page: $pageIndex } }\n orderBy: { updateTime: DESC }\n ) {\n nodes {\n id\n clientId\n clientCode\n clientName\n status\n createUser\n createTime\n remark\n updateTime\n updateUser\n }\n paginationInfo {\n pages\n current\n }\n }\n }"}, client: 172.17.0.3, server: _, request: "POST /client/graphql HTTP/1.1", host: " xx.xx.xx.xx: xx", referrer: "http://localhost:5003/"
GuoMonth commented 12 months ago

Test Case 3

Directly request local grapql services without going through the gateway

  1. web wasm client: .net 7 App, Include="GraphQL.Client" Version="6.0.0"
  2. graphql service: rust 1.73,
    async-graphql = { version = "5.0.10", default-features = false }
    async-graphql-axum = "5.0.10"
    sea-orm = { version = "0.12", default-features = false}
    seaography = {version = "^1.0.0-rc.2", default-features = false}
                Query = @"query tClientInfo($pageSize: Int!, $pageIndex: Int!) {
                    tClientInfo(
                        filters: { status: { eq: 1 } }
                        pagination: { page: { limit: $pageSize, page: $pageIndex } }
                        orderBy: { updateTime: DESC }
                    ) {
                        nodes {
                            id
                            clientId
                            clientCode
                            clientName
                            status
                            createUser
                            createTime
                            remark
                            updateTime
                            updateUser
                        }
                        paginationInfo {
                            pages
                            current
                        }
                    }
                }",
                Variables = new
                {
                    pageSize = size,
                    pageIndex = index,
                },
            };
GuoMonth commented 12 months ago

Test Case 4

apisix-integration-graphql

Requesting graphql services through the APISIX gateway.

 ~> curl -i -H 'content-type: application/graphql' -H 'Authorization: Bearer eyJ0eXxxxJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2OTgzNzxxxMDEsImtleSI6InVzZXIta2V5In0.FDfPX0YBKtbDYPBhQkf-ebrEHGTtTbcRNV0Qe8SIxxx' \
-X POST 'http://xx.xx.xx.xx:xx/client/graphql' -d '
query tClientInfo {
    tClientInfo(
        filters: { status: { eq: 1 } }
        orderBy: { updateTime: DESC }
    ) {
        nodes {
            id
            clientId
            clientCode
            clientName
            status
            createUser
            createTime
            remark
            updateTime
            updateUser
        }
    }
}'
HTTP/1.1 400 Bad Request
Content-Length: 59
Connection: keep-alive
access-control-allow-origin: *
vary: origin
vary: access-control-request-method
vary: access-control-request-headers
access-control-expose-headers: *
date: Thu, 26 Oct 2023 03:28:25 GMT
Server: APISIX/3.4.0
Access-Control-Allow-Methods: *
Access-Control-Max-Age: 5
Access-Control-Allow-Headers: *

InvalidRequest(Error("expected value", line: 2, column: 1))%

APISIX error log

172.17.0.15 - - [26/Oct/2023:03:27:17 +0000] xx.xx.xx.xx:xx "POST /client/graphql HTTP/1.1" 400 59 0.001 "-" "curl/8.4.0" 172.18.1.7:8007 400 0.001 "http://xx.xx.xx.xx:xx"
curl -i -H 'content-type: application/graphql' \
-H 'Authorization: Bearer eyJ0eXxx1QiLCJhbGciOiJIUzI1xx.eyJleHAxOjE2OTgzNzY4MDEsImtleSI6InVzZXIta2V5In0.FDfPX0YBKtbDYPBhQkf-ebrEHGTtTbcRNV0Qe8SxxU' \
-X POST http://xx.xx.xx.xx:xx/client/graphql -d '{"query":"query tClientInfo {tClientInfo(\n        filters: { status: { eq: 1 } }\n        orderBy: { updateTime: DESC }\n    ) {\n        nodes {\n            id\n            clientId\n            clientCode\n            clientName\n            status\n            createUser\n            createTime\n            remark\n            updateTime\n            updateUser\n        }\n            }\n}"}'
HTTP/1.1 404 Not Found
Date: Thu, 26 Oct 2023 03:49:09 GMT
Content-Type: text/plain; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Server: APISIX/3.4.0
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: *
Access-Control-Max-Age: 5
Access-Control-Expose-Headers: *
Access-Control-Allow-Headers: *

{"error_msg":"404 Route Not Found"}

APISIX error log

2023/10/26 03:49:09 [error] 50#50: *669595856 [lua] ctx.lua:138: get_parsed_graphql(): failed to parse graphql: Syntax error near line 1 body: {"query":"query tClientInfo {tClientInfo(\n        filters: { status: { eq: 1 } }\n        orderBy: { updateTime: DESC }\n    ) {\n        nodes {\n            id\n            clientId\n            clientCode\n            clientName\n            status\n            createUser\n            createTime\n            remark\n            updateTime\n            updateUser\n        }\n            }\n}"}, client: 172.17.0.15, server: _, request: "POST /client/graphql HTTP/1.1", host: "xx.xx.xx.xx:xx"

Directly request local grapql services without going through the gateway.

InvalidRequest(Error("expected value", line: 2, column: 3))%


- success

curl -i -H 'content-type: application/graphql' \ -X POST http://localhost:8007/client/graphql -d '{"query":"query tClientInfo {tClientInfo(\n filters: { status: { eq: 1 } }\n orderBy: { updateTime: DESC }\n ) {\n nodes {\n id\n clientId\n clientCode\n clientName\n status\n createUser\n createTime\n remark\n updateTime\n updateUser\n }\n }\n}"}'

GuoMonth commented 12 months ago

Test summary: Use curl to reproduce the error perfectly

Requesting graphql services through the APISIX gateway.

The only difference between these two requests: content-type

kayx23 commented 12 months ago

If you want to use content-type: application/graphql then you would just put the query in the data, for example:

curl -H 'content-type: application/graphql' -X POST http://xxx.xxx.xxx.xxx/graphql -d '
query getRepo { 
    owner {
        name
    }
    repo {
        created
    }
}'
GuoMonth commented 12 months ago

If you want to use content-type: application/graphql then you would just put the query in the data, for example:

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

see Test Case 4, will get 400

shreemaan-abhishek commented 11 months ago

@GuoMonth have you taken a look at this document: https://github.com/apache/apisix/blob/master/docs/en/latest/router-radixtree.md#how-to-filter-route-by-graphql-attributes?

github-actions[bot] commented 1 week ago

This issue has been marked as stale due to 350 days of inactivity. It will be closed in 2 weeks if no further activity occurs. If this issue is still relevant, please simply write any comment. Even if closed, you can still revive the issue at any time or discuss it on the dev@apisix.apache.org list. Thank you for your contributions.