Migration microservices to GraphQL

  • Published on
    14-Apr-2017

  • View
    561

  • Download
    0

Transcript

  • Migration microservices to GraphQL
  • API
  • function getUser(name: string): User { return db.getUserByName(name); } Typed request argumentes Type of response
  • RPC (1960s, CORBA, XML, JSON, Thrift) SOAP (WSDL, XML) REST (HTTP)
  • REST + People got sick of SOAP + HTTP 1/1 + Extra simplicity = fast development + Good for CRUD
  • Resources POST /users {name: "Homer"} OPTIONS /users Access-Control-Request-Method:POST
  • Resources GET /users?name=?? GET /users?name=Homer,Marge GET /users?name=..&limit&offcet GET /users?name&limit&token ⢠1 nesting level ⢠Characters escaping ⢠2048 characters
  • Resources PUT/PATCH /users/1 {name: "Homer2"} { "name": "Homer", "children": [ { "name": "Bart", }, { "name": "Lisa" } ] }
  • Backend app.post((req, res) => { const user = getUser(req.headers.user_id); const user = getUser(req.query.user_id); const user = getUser(req.path.user_id); const user = getUser(req.body.user); });
  • function getUser(name: string): User { return db.getUserByName(name); } Typed request argumentes Type of response
  • We are at wrong level  of abstraction
  • GraphQL ⢠Get what you really need ⢠Client specific ⢠Transport agnostic ⢠Rich type system ⢠A lot of web features
  • REST GraphQL Auto documented +/- Swagger, ApiDoc, Blueprint + Easy to use +/- + Easy to develop - + Flexible - + Powerful - +
  • But REST is still an industry standart
  • const QueryType = new GraphQLObjectType({ name: 'DataQuery', fields: () => ({ post: { type: PostType, args: { id: { name: 'id', type: GraphQLInt }, journal: { name: 'journal', description: 'The journal slug', type: GraphQLString }, post: { name: 'post', description: 'The post slug', type: GraphQLString } }, resolve: (user, {id, journal, post}) => { return Post.authorise(user, {id, journal, post}) .then(post => post && post.toJSON()); } } }) });
  • ⢠JSON Schema ⢠Good specification ⢠Bad ecosystem
  • "/users/findByName": { "get": { "description": "Multiple status values can be provided with comma separated strings", "operationId": "findUsersByStatus", "produces": ["application/xml", "application/json"], "parameters": [{ "name": "name", "in": "query", "description": "User name", "required": true, "type": "array", "items": {"type": "string"}, }], "responses": { "200": { "description": "successful operation", "schema": {"type": "array", "items": {"$ref": "#/definitions/User"}} }, "400": {"description": "Invalid status value"} }, "security": [{"store_auth": ["read:users"]}] }
  • Building types
  • new GraphQLSchema({ query: new GraphQLObjectType({ name: 'Query', fields: () => ({ get_user_id: { type: UserType, args: { id: { name: 'id', type: GraphQLInt } }, resolve: (id) => buildRequestWithSwagger() } }) }) }); GET /user/123 Swagger parameters
  • Mutations x-mutation POST/PUT/DELETE
  • Gateway GQL request Adapter ms1 ms2 REST request GQ L/R EST GQL/R EST function getUser(name: string): User { return db.getUserByName(name); }
  • Frontend Smart caching: GET /users GET /user/123 Helpful tools and debugging (Client knows about our schema and types) Get only data that you need
  • Frontend ⢠Cursor connections ⢠Subscriptions ⢠Batching ⢠Defered delivering ⢠Fragments composition
  • Precautions No GraphQL types namespaces campaigns_get_campaigns_shop_shop_id_products_ids No validation for input types lokka React Apollo Vanila
  • Thanks github.com/yarax/typelint twiitter.com/raxpost yarax.ru http://github.com/yarax/typelint http://twiitter.com/raxpost http://yarax.ru/ Migration microservices to GraphQL API Slide 3 Slide 4 REST Resources Resources Resources Backend Slide 10 We are at wrong level of abstraction GraphQL Slide 13 But REST is still an industry standart Slide 15 Slide 16 Slide 17 Slide 18 Building types Slide 20 Mutations Slide 22 Frontend Frontend Precautions Thanks