Vue-apollo: Cannot call API from GraphQL SPRQ server

Created on 12 Sep 2018  路  5Comments  路  Source: vuejs/vue-apollo

Create GraphQL server

Checkout the project https://github.com/leangen/graphql-spqr-samples.
Move to spring-boot-sample folder.

Disable cors by editing line 63 in file:

/src/main/java/io/leangen/spqr/samples/demo/controller/GraphQLSampleController.java

@CrossOrigin(origins = "*", allowedHeaders = "*" )
@PostMapping(value = "/graphql", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)

Run in http://localhost:7777

mvn spring-boot:run

Test

Query

{
  getNormalGreeting(person: {
    firstName: "Phong"
    lastName:"Ca"
  })
}

Response

{
  "data": {
    "getNormalGreeting": "Hello Phong!"
  }
}

Create vue-apollo project

HelloComponent

import gql from 'graphql-tag'
const axios = require('axios');
const DEMO = gql`
  {
    getNormalGreeting(person: {
      firstName: "Phong"
      lastName:"Ca"
    })
  }
`
export default {
  name: 'HelloWorld',
  apollo: {
    customers: {
      query: DEMO 
    }
  },
  data () {
    return {
      customers: []
    }
  },
  created: function() {
    axios.post('http://localhost:7777/graphql', {
      query: `
        {
          getNormalGreeting(person: {
            firstName: "Phong"
            lastName:"Ca"
          })
        }
      `
    })
    .then(function () {
    })
    .catch(function () {
    })
  }
}

Use axios

Request

Request URL: http://localhost:7777/graphql
Request Method: POST
Status Code: 200 
Remote Address: [::1]:7777
Referrer Policy: no-referrer-when-downgrade

Response Headers
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: http://localhost:8080
Content-Type: application/json;charset=UTF-8
Date: Wed, 12 Sep 2018 04:40:54 GMT
Transfer-Encoding: chunked
Vary: Origin
X-Application-Context: application:7777

Request Headers
Accept: application/json, text/plain, */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9,vi-VN;q=0.8,vi;q=0.7
Cache-Control: no-cache
Connection: keep-alive
Content-Length: 158
Content-Type: application/json;charset=UTF-8
Host: localhost:7777
Origin: http://localhost:8080
Pragma: no-cache
Referer: http://localhost:8080/
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36 

Request Payload
{"query":"\n        {\n          getNormalGreeting(person: {\n            firstName: \"Phong\"\n            lastName:\"Ca\"\n          })\n        }\n      "}

Response

{
  "data": {
    "getNormalGreeting": "Hello Phong!"
  }
}

Use gql

Request

Request URL: http://localhost:7777/graphql
Request Method: POST
Status Code: 400 
Remote Address: [::1]:7777
Referrer Policy: no-referrer-when-downgrade

Response Headers
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: http://localhost:8080
Connection: close
Content-Type: application/json;charset=UTF-8
Date: Wed, 12 Sep 2018 04:40:54 GMT
Transfer-Encoding: chunked
Vary: Origin
X-Application-Context: application:7777

Request Headers
accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9,vi-VN;q=0.8,vi;q=0.7
Cache-Control: no-cache
Connection: keep-alive
Content-Length: 125
content-type: application/json
Host: localhost:7777
Origin: http://localhost:8080
Pragma: no-cache
Referer: http://localhost:8080/
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36

Request Payload
{"operationName":null,"variables":{},"query":"{\n  getNormalGreeting(person: {firstName: \"Phong\", lastName: \"Ca\"})\n}\n"}

Response

{
  "timestamp": 1536727254695,
  "status": 400,
  "error": "Bad Request",
  "exception": "org.springframework.http.converter.HttpMessageNotReadableException",
  "message": "JSON parse error: Can not deserialize instance of java.lang.String out of START_OBJECT token; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.lang.String out of START_OBJECT token\n at [Source: java.io.PushbackInputStream@58b6376; line: 1, column: 35] (through reference chain: java.util.LinkedHashMap[\"variables\"])",
  "path": "/graphql"
}
upstream

All 5 comments

This look like an apollo-client issue.

I found some problem, trying compare pet-clinic with my own backend. Problem found on my own backend, so I think this is your backend issue with SPQR server

I found some problem, trying compare pet-clinic with my own backend. Problem found on my own backend, so I think this is your backend issue with SPQR server

Have you solved this issue of SPQR?

I found some problem, trying compare pet-clinic with my own backend. Problem found on my own backend, so I think this is your backend issue with SPQR server

I solved it like below, the key is "Map" instead of "Map"

@PostMapping(value = "/graphql", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ResponseBody
    public Map<String, Object> graphql(@RequestBody Map<String, Object> request, HttpServletRequest raw) {
        ExecutionResult executionResult = graphQL.execute(ExecutionInput.newExecutionInput()
                .query(request.get("query").toString())
                .operationName(request.get("operationName") != null ? request.get("operationName").toString() : null)
                .context(raw)
                .build());
        return executionResult.toSpecification();
    }

It has to do with graphql-variables; the POST-request is a JSON structure with query/operationName being strings, and variables being an object:

    @PostMapping(value = "/graphql", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ResponseBody
    public Map<String, Object> graphql(@RequestBody Map<String, Object> request, HttpServletRequest raw) {
        ExecutionResult executionResult = graphQL.execute(ExecutionInput.newExecutionInput()
                .query((String) request.get("query"))
                .operationName((String) request.get("operationName"))
                .variables((Map<String, Object>) request.get("variables"))
                .context(raw)
                .build());
        return executionResult.toSpecification();
    }
Was this page helpful?
0 / 5 - 0 ratings

Related issues

mathe42 picture mathe42  路  4Comments

apertureless picture apertureless  路  4Comments

agosto-chrisbartling picture agosto-chrisbartling  路  4Comments

anymost picture anymost  路  3Comments

sadhakbj picture sadhakbj  路  3Comments