Share
Embed
GraphQL for service-to-service communication protocol
GraphQL Tokyo Meetup #9 at Repro Inc.
qsona
December 06, 2019
Transcript
34 slides
-
Today's Topic: GraphQL is a suitable protocol not only for
Frontend but also for service-to-service communication -
Microservices • Number / Size of services, I don't care
(just assume N>=2) • They cooperate with each other by communicating on some API protocol -
Many people use REST / gRPC • For internal API
protocol, GraphQL is currently not a popular choice • Of course, REST (JSON over HTTP) and gRPC are very good options -
Why don't people use GraphQL? • "No need to use
GraphQL internally because the network cost of internal communication is low" • • GraphQL has many other benefits! -
3 reasons why we should use GraphQL for service-to-service API
protocol • 1. Easy to evolve our services • 2. Good API Interface and documentation system • 3. Easy to make GraphQL Aggregation Layer for Frontend -
3 reasons why we should use GraphQL for service-to-service API
protocol • 1. Easy to evolve our services • 2. Good API Interface and documentation system • 3. Easy to make GraphQL Aggregation Layer for Frontend -
Make our services easy to evolve • Services need to
be evolved independently • This is one goal of microservices architecture • We often want to make changes for APIs • explicitly or implicitly • All the changes possibly break the consumers using that service -
How to avoid breaking consumers? • Consumer won't be broken
by irrelevant changes • Provider can be aware when a change will break some consumers -
• Consumer won't be broken by irrelevant changes • Provider
can be aware when a change will break some consumers -
A bad example (in Ruby) Response Body { "a": 1,
"b": 2 } • An example of consumer code • Do you find why this code is bad? -
Response Body { "a": 1, "b": 2, "c": 3 }
A bad example (in Ruby) • It's not tolerant because it will be broken by just adding a new field to the API payload -
Response Body { "a": 1, "b": 2, "c": 3 }
How to fix it • We must explicitly pick the fields we use -
Tolerant Reader in GraphQL • In GraphQL world, consumers are
always Tolerant at a certain level • Consumers explicitly define what they need • If some unused fields are added / deleted, it should never be broken -
• Consumer won't be broken by irrelevant changes • Provider
can be aware when a change will break some consumers -
How can providers be aware of the breaking changes itself?
• Ask to other teams manually • It's necessary, but we want to reduce it as much as possible • Use Contracts between Consumer and Provider • (c.f. Consumer-driven Contract Testing) • Check Production API Logs -
How providers can be aware of the breaking changes itself?
• Use Contracts between Consumer and Provider • Check Production API Logs -
Persisted Query • A technique that forces consumers to pre-register
queries before they use them (e.g. build steps) -
Persisted Query • A technique that forces consumers to pre-register
queries before they use them (e.g. build steps) • Benefits: • Avoid executing unknown queries (which can be harmful) in provider service • Reduce the size of request payload • Enable to use HTTP GET Method, and cache on CDN -
Persisted Query • Persisted Query can be regarded as Contract
• Provider can check the persisted queries, and know what kind of fields are being used now • Provider can write tests to assure these queries can be used correctly, and run them in CI (≒ Consumer-driven Contract Testing) -
How providers can be aware of the breaking changes itself?
• Use Contracts between Consumer and Provider • Check Production API Logs -
Field-level Logs • On GraphQL, we can check the logs
in field-level • If a field doesn't show up in logs, that field is most likely deletable • On REST/gRPC, we can see only logs per endpoints -
GraphQL helps us to evolve our services! • Consumer won't
be broken by irrelevant changes • Provider can be aware when a change will break some consumers -
3 reasons why we should use GraphQL for service-to-service API
protocol • 1. Easy to evolve our services • 2. Good API documentation/type system • 3. Easy to make GraphQL Aggregation Layer for Frontend -
API documentation is important for microservices • API documentation makes
our teams loose-coupling • It's also important that API documentation is always new and valid • It should be declarative and be used for request/response validation -
GraphQL and API docs • GraphQL Type system and GraphiQL
perfectly works • Compare to OpenAPI, GraphQL Type system is tightly coupled with the actual implementation • OpenAPI itself is just a declarative documentation • To validate request and response, we need some other tool (e.g. interagent/committee is an implementation for Ruby) -
3 reasons why we should use GraphQL for service-to-service API
protocol • 1. Easy to evolve our services • 2. Good API documentation/type system • 3. Easy to make GraphQL Aggregation Layer for Frontend -
GraphQL Aggregation Pattern • This pattern seems getting popular •
It indicates that GraphQL API is very useful for Frontend Developers -
GraphQL Aggregation Pattern • There is an Impedance Mismatch between
REST/gRPC and GraphQL • Mapping REST/gRPC API to GraphQL Type is not just annoying, but also increasing points of failure • I feel it's usually a bit excessive architecture • (Sorry, I know google/rejoiner but didn't try by my hand) -
If Backend APIs are also GraphQL • No impedance mismatch
• It can reuse downstream schemas, so it can be thin layer • => Apollo Federation -
Conclusion • GraphQL is also good for service-to-service communication protocol
because • It makes easy to evolve our services without breaking consumers • It provides good API type and documentation system • It makes easy to make GraphQL Aggregation Layer for Frontend (which is already thought to be very useful)