You are on page 1of 9

3/16/2018 Sharing data in a Microservices Architecture using GraphQL

Images haven’t loaded yet. Please exit printing, wait for images to load, and try to
Bruno Soares Follow
Jul 12, 2017 · 7 min read print again.

Sharing data in a Microservices
Architecture using GraphQL
Here at GetNinjas we’ve faced some problems integrating components
of our Microservices Architecture and exploring available options,
GraphQL showed up as an excellent t. I’ll focus on exploring problems
with three common ways to do that, and in the end suggest GraphQL as
a better option for some cases.

Common strategies
Strategy #1 — Share database access
Integrate systems by their databases seems to be so easy that we feel
seduced to do this. All we have to do is share databases access among
the services, so the system A can access the database of the system B
and so forth. What is the problem with this approach? Here is a list of
some of them:

#1.1 Performance
Problems with performance in the service A can a ect the system B and
make it hard to scale them independently, actually they are not
independent.

#1.2 Duplicated business rules


Imagine that the system A have a list of users with a status property
that indicates if the user is activated or not, if the service B fetches
these users directly from the A’s database, you’ll have to lter by
activated users in two places, if this rule changes, the chances of one of
them becoming outdated is high.
 
Ok, this strategy breaks basic rules of Microservices so it’s not worth it
continuing analyzing its problems.

Microservices prefer letting each service manage its own database, either
di erent instances of the same database technology, or entirely di erent
database systems.(Decentralized Data Management)
. . .

https://labs.getninjas.com.br/sharing-data-in-a-microservices-architecture-using-graphql-97db59357602 1/9
3/16/2018 Sharing data in a Microservices Architecture using GraphQL

Strategy #2 — Sync all data in a centralized database
If you have a data warehouse you may be feel tempted to use it but,
here’s some details you have to pay attention.

#2.1 Di erent types of data source


If you have components of di erent data source types in your
architecture, for instance, some of them using PostgreSQL, MySQL
others using MongoDB, Redis, Cassandra, Neo4j… It can be hard to
sync all of them in a single centralized database due to di erent
formats.

#2.2 Racing conditions


The sync takes some time to occur, then when a service tries to access
information that was not yet synced, that service will work with an
outdated version of the data and you will start to experience some
random problems. The common solution is to add some delay to
request that information. Actually it’s not a real solution because it
brings other problems.

#2.3 Changes in the service’s schema


When you change the schema of some service, it will be synced, and
then, other services that relies in the old format will break. You can
minimize this problem by writing a giant integration test that runs after
changes on each component, but a change in one service should not
impact other service (See Componentization via Services).

#2.4 Change the type of data source


You may need to change the type of your data source, for example from
a document to a relational (here at GetNinjas we had a case like that).
This change will impact all the services using this data.

#2.5 Dynamic calculated information


There are some cases that the information is not persisted but is
calculated before the use, like the URL of an user’s avatar. This type of
information lives inside the application in places like Decorators,
Presenters, con g les, not persisted in the database and obviously it
will not be synced, so, in this strategy you will have to duplicate the
logic to accomplish the same result URL.

#2.6 Duplication of common queries


Let’s say you have a query that returns the top ve similar products and

https://labs.getninjas.com.br/sharing-data-in-a-microservices-architecture-using-graphql-97db59357602 2/9
3/16/2018 Sharing data in a Microservices Architecture using GraphQL

other service want to use it. In a synced database strategy you will need
to duplicate that query, the problem with it is obvious, when the query
is changed, you will need to change all versions too.

#2.7 Data format


It's a good practice to store the data in raw (without format) and format
them when displaying. Using an API to integrate systems you can also
return data formatted and the logic to format that data is not spread
out the entire architecture. In this strategy you will have to save the
data formatted or reimplement the logic.

Sync databases in one big place can be a good choice for analysis
purpose, but to share data between services, not so much.

. . .

Strategy #3 — REST APIs
At this point, things start to get much better. But we can list a few
problems.

#3.1 Hard to reuse existing endpoints


Most likely, each service will need a set of speci c elds, adding new
elds to the endpoint will not only a ect all services consuming this
endpoint, but it will also decrease the performance of the API.

#3.2 Create speci c endpoints for each service


Seems to be a good idea, but as you start to add more and more
endpoints, the API becomes messy and the development time grows as
well. The need for a documentation system like Swagger begins to
make sense.

For some cases you can stop reading here, REST APIs can do a really
great job integrating services, BUT GraphQL is here and understanding
this tool can be very useful!

. . .

GraphQL as an API for some services
I’ll describe below a few bene ts of GraphQL over REST.

https://labs.getninjas.com.br/sharing-data-in-a-microservices-architecture-using-graphql-97db59357602 3/9
3/16/2018 Sharing data in a Microservices Architecture using GraphQL

I'm preparing a post about pain points of GraphQL, stay tuned :)

Update 09/19/17: Pain Points of GraphQL

Flexibility
You can query the schema navigating through multiple resources by
their relations saving round trips to the server.

Performance
Ask for only what you need, not a resource that responds with all data.

Github’s GraphQL API example of query/response using the GraphiQL IDE.

Highlights

• Query multiple "resources" at the same time in a single request (in


this case user and repository).

• The query matches exactly the response. You do not need to read
the documentation or run the request to know the response
structure.

https://labs.getninjas.com.br/sharing-data-in-a-microservices-architecture-using-graphql-97db59357602 4/9
3/16/2018 Sharing data in a Microservices Architecture using GraphQL

• You can pass arguments to elds (like in the avatarUrl that


receives size).

• Query nested resources (e.g. organizations are children of user).

• Pagination ready to be used (see Relay Cursor Connections


Speci cation).

Documentation
Document eld by eld during development.

Github’s GraphQL API example of auto-generated documentation using the GraphiQL IDE.

https://labs.getninjas.com.br/sharing-data-in-a-microservices-architecture-using-graphql-97db59357602 5/9
3/16/2018 Sharing data in a Microservices Architecture using GraphQL

Highlights:

• The description of types or elds appears at the top of the


documentation window.

• The type system helps you de ne your schema in a more natural


way.

• You can mark elds as deprecated (like databaseId of


Organization Type).

Development
Evolve the entire API schema instead of only one REST API endpoint.
When you add a eld it can be used by other consumers.

Organic versioning
Simply add elds when you need or mark them as deprecated when
you plan to stop using them.

Monitoring
Track the usage of each eld in your API, you can track who is using,
performance and the usage of deprecated elds.

Of course that GraphQL will not replace all cases that we are
accustomed to solve with other technologies, there are so many out
there, RESTful, SOAP, Sockets, Protobuf, some kind of binary protocol
over UDP, Queues, etc. Knowing other options will help you achieve
your goals quickly and better.

. . .

GraphQL as API Gateway
Instead of requesting information to a speci c service you can request
that information to an API Gateway which abstracts the service that is
the owner of the data.

Let’s use an online store as example. Services that have more


information to expose may use GraphQL and services that exposes less
may use a simple REST API.

https://labs.getninjas.com.br/sharing-data-in-a-microservices-architecture-using-graphql-97db59357602 6/9
3/16/2018 Sharing data in a Microservices Architecture using GraphQL

GraphQL as API Gateway.

In this approach it doesn’t really matter if the services uses a REST API
or a GraphQL API. Actually, if your service is really thin GraphQL will
only add an extra complexity, so a simple REST API can be better.

Merging the APIs in one place
Update: 02/26/2018

At this point, you may be asking yourself, how to join all APIs in only one
GraphQL schema? There are some tools to help you :)

GraphQL schema stitching


I guess that this term was created by Apollo team. It refers to the action
of merge GraphQL schemas.

This post summarizes how schema stitching works and here, you cam
nd examples to build it using the Apollo GraphQL Tools.

Another interesting too to combine GraphQL schemas is the graphql-


weaver (A tool to combine, link and transform GraphQL schemas), that
actually was born before the tools created by Apollo.

https://labs.getninjas.com.br/sharing-data-in-a-microservices-architecture-using-graphql-97db59357602 7/9
3/16/2018 Sharing data in a Microservices Architecture using GraphQL

Reimplement the schema


In this situation, you can rewrite all the schema, fetching the data from
each eld resolver, like in this PersonType example:

...
person: {
type: PersonType,
args: {
id: { type: GraphQLString },
},
resolve: (root, args) => {
fetch(`${BASE_URL}/person/${args.id}/`)
.then(res => res.json())
.then(json => json.person)
},
},
...

If you choose to go in this way, take a look at Wrapping a REST API in


GraphQL, and DataLoader (to prevent N+1 fetches).

. . .

Conclusion
Integrate services by their databases is not a good option, an
architecture that takes advantage of the best of each technology shall
bring better results (as always).

Special thanks to Cristhiane Almeida, Daniel Tamai and Ion D. Filho,


who helped review an earlier draft of this post.

I hope you’ve enjoyed the ideas presented here. If you liked it, please
consider tapping or clicking the icon to recommend it to others so
they can enjoy it too. And feel free to share it widely in your favorite
social network :-)

https://labs.getninjas.com.br/sharing-data-in-a-microservices-architecture-using-graphql-97db59357602 8/9
3/16/2018 Sharing data in a Microservices Architecture using GraphQL

https://labs.getninjas.com.br/sharing-data-in-a-microservices-architecture-using-graphql-97db59357602 9/9

You might also like