26
Migration microservices to GraphQL

Migration microservices to GraphQL

Embed Size (px)

Citation preview

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-mutationPOST/PUT/DELETE

Gateway

GQL request

Adapter

ms1

ms2

REST request

GQL/REST

GQL/REST

function getUser(name: string): User { return db.getUserByName(name);}

Frontend

Smart caching:GET /usersGET /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

PrecautionsNo GraphQL types namespaces

campaigns_get_campaigns_shop_shop_id_products_ids

No validation for input types

lokka

ReactApolloVanila

Thanks

github.com/yarax/typelint

twiitter.com/raxpost

yarax.ru