2018年11月13日 星期二

GraphQL 學習心得

GraphQL

GraphQL - A Query Language for APIs

GraphQL is a query language designed to build client applications by providing an intuitive and flexible syntax and system for describing their data requirements and interactions. — from Facebook

Agenda

  • Why GraphQL
  • Java Library
  • Example Project
  • Problem
  • GraphiQL

Why GraphQL


Overfetching

Downloading superfluous data
Overfetching means that a client downloads more information than is actually required in the app.

Underfetching

Underfetching generally means that a specific endpoint doesn’t provide enough of the required information. The client will have to make additional requests to fetch everything it needs.

Browser Connection Limit

Max Number of default simultaneous persistent connections per server/proxy:
Firefox 3+: 6
Opera 12: 6
Safari 5: 6
IE 7: 2
IE 8: 6
IE 10: 8
Chrome: 6

HTTP connection cost


REST vs GraphQL


Java Library


GraphQL and GraphiQL Spring Framework Boot Starters

Repository contains:
graphql-spring-boot-starter to turn your boot application into GraphQL server
graphiql-spring-boot-starter to embed GraphiQL tool for schema introspection and query debugging

graphql-java-tools

com.coxautodev.graphql.tools.SchemaParser
Schema First
type Link {
  url: String!
  description: String!
}

type Query {
  allLinks: [Link]
}
schema.graphqls

graphql-java-annotations

Code First
public class SomeObject {
  @GraphQLField
  public String field;
}

// ...
GraphQLObjectType object = GraphQLAnnotations.object(SomeObject.class);

java-dataloader

DataLoader is a generic utility to be used as part of your application’s data fetching layer to provide a simplified and consistent API over various remote data sources such as databases or web services via batching and caching.

Example Project

  • GraphQLxSpringBoot
  • GraphQLxSpringMVC

GraphQLxSpringBoot

Spring Boot plugin requires Gradle 4.0 or later.
plugins {
    id 'org.springframework.boot' version '2.0.4.RELEASE'
}

apply plugin: 'java'
apply plugin: 'io.spring.dependency-management'

dependencies {
    compile("org.springframework.boot:spring-boot-starter-web")
    compile group: 'com.graphql-java', name: 'graphql-spring-boot-starter', version: '4.0.0'
    compile group: 'com.graphql-java', name: 'graphiql-spring-boot-starter', version: '4.0.0'
}
gradle bootRun

GraphQLxSpringMVC

dependencies {
    compile group: 'org.springframework', name: 'spring-webmvc', version: '4.3.16.RELEASE'
    compile group: 'com.graphql-java', name: 'graphql-java', version: '8.0'
    compile group: 'com.graphql-java', name: 'graphql-java-tools', version: '5.2.3'
}
gradle appRun

Problem


不支援泛型


沒有 Inheritance



沒有 Overload

a particular field must always return the same type
type Link {
  url: String!
  description: String!
}

type Query {
  links: [Link]
  links(limit: Int): [Link]
}
error


Map Scalar

public class MapScalar {

  public static final GraphQLScalarType MAP = new GraphQLScalarType("Map", "A custom map scalar type", new Coercing() {
    @Override
    public Object serialize(Object dataFetcherResult) throws CoercingSerializeException {
      Map map = null;
      try {
        map = Map.class.cast(dataFetcherResult);
      } catch (ClassCastException exception) {
        throw new CoercingSerializeException("Could not convert " + dataFetcherResult + " into a Map", exception);
      }
      return map;
    }

    @Override
    public Object parseValue(Object input) throws CoercingParseValueException {
      return null;
    }

    @Override
    public Object parseLiteral(Object input) throws CoercingParseLiteralException {
      return null;
    }
  });
}

Error(1)

status code always 200 even exception…
{
  "errors": [
    {
      "message": "Invalid Syntax",
      "locations": [
        {
          "line": 1,
          "column": 0
        }
      ]
    }
  ]
}

Error(2)

{
  "data": {
    "Profile": null
  },
  "errors": [
    {
      "message": "Exception while fetching data (/Profile/basic) : Data Not Found, pid:3112122",
      "locations": [
        {
          "line": 3,
          "column": 5
        }
      ],
      "path": [
        "Profile",
        "basic"
      ]
    }
  ]
}

GraphiQL

An in-browser IDE for exploring GraphQL.
autocomplete: option(control) + space

Reference