Professional Documents
Culture Documents
Key Takeaways
The winner is, of course, “it depends.” Each technology has strong benefits, but those come
with trade-offs. Your needs may best be served by a combination of technologies.
REST, or at least JSON over HTTP, is the most ubiquitous standard for web-based APIs.
This means it’s easy to get started, you can use a wide variety of languages, and it works
natively with web browsers.
In their own way, GraphQL and gRPC address some of the limitations of REST.
GraphQL allows a client to specify just the information they need, which can greatly reduce
duplicate or unnecessary data being transmitted. But, it requires additional setup and
training.
gRPC is built for fast transport, leveraging HTTP/2. This requires a well known contract,
typically using Protocol Buffers, that is shared by the client and server.
Subscribe on:
Transcript
Welcome to the API showdown. I'm joined by three panelists, each chose to be a representative
of one particular API technology, more or less. Any good architect knows the only time you
should ever use always or never is to say we will never do an absolute. I don't want to paint any
of the panelists into a corner as only an expert on one topic. It's just a helpful way to create a
discussion with diverse opinions, because we really want to understand, what are the tradeoffs
you need to consider when evaluating your options?
Background
Representing gRPC, we have Alex Borysov. Alex is currently an engineer at Netflix, and was
previously at Google, who gave us the g in gRPC.
Michelle Garrett is part of the team building Twitter's large scale GraphQL API. Twitter picked
her up after she did an amazing job implementing GraphQL at Condé Nast, where surprisingly,
they did not put the GQ in GraphQL.
Matt McLarty is a Global Field CTO for MuleSoft, co-author of two O'Reilly books on
microservice APIs architecture. He's not behind a microphone here at QCon, he's behind a
microphone as co-host of the 'APIs Unplugged' podcast.
McLarty
: I'm only choosing REST, because CORBA was not an option. It's a great point, you could
probably write chair or token size books on the history of REST and APIs. Roy Fielding had the
dissertation, which defined the style of Representational State Transfer. He was more like
showing in a thesis, here's how you can define an architectural style, and let's choose how the
web works, so we'll use REST. In terms of solving the problem, I think what's really interesting
is, it was a very organic adoption of REST in a lot of different uses. At the time, there was a lot of
energy behind SOAP in the enterprises, here's a way of using web technologies to connect things,
and all these very prescriptive standards about how to write SOAP messages. REST's rise was
really in response to, in rebellion against this SOAP. It started just being like, here's a practical
way of doing things. What if we just use HTTP verbs and define things as resources over the
web? If I had to generalize what problem it was meant to solve, it's like the web itself. If we go
underneath the browser on webs, how do we just plug things together using web protocols?
That's why I think part of the power of REST and part of the ubiquity of REST has been its wide
adoption in many different use cases. I think, people learning it in one area and then applying it
another.
It used to be you just connect to the eBay API or something, using REST in the early days. Then
it was like, what if we use a REST API to do deployments or do some management over web
networks. Then it was, there's these mobile devices. How are we going to expose systems to the
mobile? We can use this REST thing that seems to be working in other places. It really has been
a very organic thing. Some of the reasons that new protocols have emerged has probably been
based on its ubiquity and the compromises that come with that, and the ambiguity that comes
with that. The story of REST is really the story of the web.
Garrett: GraphQL was originally developed by Facebook in 2012. Then the spec was first
released publicly in 2015. It's been around, open source for about six years now. The history of
GraphQL at Facebook is quite widely written about and you can look up online and find out all
about it. I'll give you a brief TLDR. Ultimately, the first ever implementation of GraphQL was the
Facebook mobile newsfeed API. The problem that Facebook engineers were trying to solve with
GraphQL was that pain point of having to make loads of different API requests back and forth
from different endpoints in order to get all of the data that was necessary to render a view, which
in this case, is the very complicated Facebook newsfeed where everything is interconnected and
nested with each other. This was coupled with a problem at the time of people shifting to mobile
and using really bad 3G mobile networks.
GraphQL was invented to solve those problems at Facebook. The fresh idea that GraphQL
brought to the table was really thinking about data in terms of a graph instead of multiple
endpoints. Unlike REST APIs, which expose data via multiple different endpoints, GraphQL
exposes all of the data through a single endpoint that is flexible. When you build a GraphQL API,
you're really trying to build a unified data graph, which client developers can then query a subset
of based on what their needs are. Really, the key feature of GraphQL, and what everyone loves
about it, and what is innovative about it, is that it empowers client developers to select exactly
the data that they want from the API, and get back exactly what they've asked for without
anything else. They get it all in one go. That's GraphQL.
Betts
: Nice and shiny.
The idea was not to create an architectural style. The idea was not to create a query language.
The idea was to offer a collection of technologies that help you as a developer, build and run
distributed systems with a large number of remote calls and hide all the HTTP/2 protocol
implementation detail. Give you as a developer a framework with efficient wire format, for
serialization, deserialization, and built-in features you will need to run your system, and help
you focus on modeling your business oriented actions as opposed to HTTP protocol details.
Borysov
: If you're designing a low-latency, highly scalable distributed system, you should at least
consider using gRPC. The default out of the box implementation is using protocol buffers as an
ideal and serialization mechanism. I said by default, because, again, gRPC is actually encoding
agnostic. Technically, you can use gRPC without protobuf, but let's stick with protobuf. Protobuf
is wire efficient. You're not sending giant string payloads. You're not spending resources on
parsing those strings. In some languages, string parsing can be extremely inefficient. If your
backend is used by mobile clients, they will be more tolerant to bad network connections
because you just send less data over the wire. Those clients will need to spend less CPU on
deserialization, which helps with battery life.
On the other hand, if you're building a backend system that includes or at some point will
include hundreds or thousands of interconnected microservices, gRPC will offer efficiency and
speed, and also will provide built-in features like deadline propagation, cascading cancellations,
retries, request hedging, and so on. Or perhaps at some point, you will need streaming APIs.
Your application needs to stream multiple requests or multiple responses in one RPC
interaction. Maybe your application streams data from sensors or stock price and sub-
millisecond latency is very important for your business, you may need flow control or
backpressure for those streaming APIs. Streaming RPCs with flow control have first class
support in gRPC. You will probably need TLS. At some point, you will need load balancing,
custom authorization, monitoring. gRPC provides building blocks with default implementations
and extension points for all those concepts. The best thing is, you don't have to think about all
those features until you need them. gRPC is very easy to start with. You can give it a try just for
expressive language-neutral ideal, and auto-generated client libraries, and later start using those
additional features and extensions when you need them.
Garrett: I have two use cases. The first one is where you have one client application with many
data sources. The second use case is when you have many client applications and one shared
data source. Let's talk about the use case where you have multiple clients that need to use the
same set of data in different ways. For example, you might have a web application and a mobile
application, which both need to access the same set of data but the view looks different in both
of those applications. The interface that they need of that data is completely different. Trying to
share a REST API between these two clients can result in really bloated endpoints with lots of
data that is unnecessary to one or the other clients. If you use GraphQL, on the other hand, it
allows both of these clients to share the same set of core data, but they can use it in a way that
actually makes sense for them. They can ask specifically for the data fields that they want and
they're not going to be burdened by the data needs of the other applications that are sharing the
same dataset. That's number one.
My second beautiful use case for GraphQL is when you have multiple data sources for a single
application, and you want to streamline those into a single interface. Say you're building a client
application, and it has loads of data sources, say like, three REST APIs, a JSON file, and a
database. Maybe one of those REST APIs is a horrible legacy API that people are scared to touch,
and it's undocumented, and the naming is horrible. You can't really change anything in it
because it has to remain backwards compatible for other applications. In this case, you have
disparate data sources and GraphQL is the perfect tool for the job to unite those data sources in
a data layer. You can wrap all of them in a single GraphQL layer. This layer allows you to hide
the ugliness of the underlying services. You can name fields, how you like. You can hide
implementation details. You can relate data from the different data sources together in a way
that makes sense, but you don't have to expose that they come from different services to the
client. Basically, you create a nice streamlined data layer for your application.
McLarty
: In this moment of being personally insulted, I'm just going to reflect for a second and invert
things a little bit. Honestly, I think this question to me raises the question of, what's the right
way of deciding. What criteria do you use to decide on the protocol? I think we've heard some
really good technical justifications. We've heard some design justifications factoring in
consumer needs. The reality is, depending on what perspective you're coming from, you could
arrive at different answers. I just wanted to pause and step out of character for a moment and
say, you really need to think about what your consumers need first, I think. Especially, you may
be in a situation where you own both ends of the pipe, and so you've got a little more liberty to
make decisions based on other criteria. For me, step one is, what do my consumers need? You
might have the perfect technical justification to go with one protocol over the others, but if your
consumers really need it in one format, then that should override things, or maybe they need
multiple.
The answer for REST is like everything else, or those plus everything else. I think that what
we've seen is, first of all, how do you define REST? Because even within the community, there's
lots of disagreements around that. I agree, there are some ugly REST APIs that could use some
abstraction, but it's not really dictated by the protocol. That flexibility is, again, its strength, and
also leads to some of the pitfalls. I would say in general where you meet the web, or maybe more
abstractly, when you don't know who your consumers are, so when you're really aiming at an
unknown audience. I think it is very beneficial to say, REST is the great equalizer here. That if
you don't know who's going to consume it, it's table stakes to say, have a RESTful interface. You
know that there's going to be people who know how to use that. Then, maybe there'll be reasons
to specialize on other protocols later. Even in the examples, we'll see some organizations will use
a RESTful interface as an abstraction on top of a gRPC channel internally as a way of opening up
to the web. Or, you'll see RESTful APIs being building blocks for a GraphQL endpoint, that's
aggregating things. There's lots of common authorial scenarios as well. My things would be,
think about what your consumers need, and if you're not totally sure of what your consumers
need, then that's probably where REST is an obvious choice.
Borysov
: I'll start with some other's answers for gRPC, for example, when your language is not
supported. Code generation comes with the downside that only 11 languages are supported. If
your language is not on the list, you're out of luck. Or, which can be even more important, if your
language is on the list but your consumers cannot use or don't want to use a language that is
supported, they should probably look or you should probably build your API with something
else. In those cases, you can create reverse proxies, you can use projects like gRPC gateways. It
creates REST endpoints for gRPC services, or you can use Envoy with gRPC-JSON transcoders
that translates RESTful requests into gRPC. Those solutions are more like workarounds. If you
know that a significant amount of your API consumers will not be able to use native gRPC
libraries, it's probably not the best tool to use.
Also, if you're building like one of APIs that you know you will sunset soon, for example, you
build migration APIs or something, the schema overhead might not be worth it. Or, if you're
building a service that only talks to a web browser, and it doesn't call any backend services, it
just calls the database, for example, it's a simple application, or you're building a monolith for a
good reason, in those scenarios, you can get more benefits from another technology, GraphQL or
REST. Yes, you may still be able to use gRPC, and you still will benefit from language neutral
contract, from code generation. To talk to the web browser, you will need gRPC web proxy, and
communication between proxy and the web browser will still be HTTP/1.1. If your only
integration point is web browser, gRPC is probably not the best choice. You should really
understand what your complexity is. You should start with understanding what your complexity
is. If your complexity is in QPS, throughput, latencies, you're concerned about optimizing tail
latencies, go with gRPC. If your complexity is in complex domain that you have rich UI
application pulls data from dozens of services, GraphQL can be the better choice.
Borysov
: First, your consumer and producer client and server, they have to agree on the protocol. gRPC
is an API-first framework, so an API contract is not an afterthought. It's the very first thing you
start with. Again, for simplicity, let's pretend it is only protobuf. Unlike REST or GraphQL, in
gRPC you model actions. You model your methods. You define your service, which is just a
collection of actions that your server can do. Your server can be resource oriented, but it doesn't
have to be. You define what it can do, and this action can be defined around data entities or not.
Then, even though gRPC is based on HTTP protocol, gRPC does not expose any HTTP details, so
this protobuf schema is very simple. You define your request as a proto message, your response
as a proto message, and your method. Then you will need to use protocol buffer compiler with
gRPC plugin to generate classes for both consumer and producers.
For example, let's say we define the QCon service with two actions, attend the session, and
attend lunch. Two most important things you can do during the conference. Attend session takes
request, it returns a response, so your API definitions will be compiled into classes in a language
of your choice. For example, let's say we use proto compiler with gRPC Java plugin. For
backend, it generates an abstract class called QCon service Impl base, and backend developer
would need to extend this class, override that attend session, override attend lunch method, so
no annotations, no mapping, you just need to implement methods in your language. For the
client, proto compiler generates client stubs and client libraries, these methods attend session
and attend lunch. In fact, it generates two types, two subsets of client libraries: synchronous and
asynchronous. In Java, it will generate three clients: blocking client, callback based client, and
future based client. gRPC encourages you to use non-blocking clients, but you can start with
simple blocking client and then switch to asynchronous later on if you need to.
You can just start with instantiating those generated clients, and you use your data entities, you
build the request, and then call this method to invoke a server. All the heavy lifting, serialization,
deserialization, opening streams, managing connections work in this HTTP/2 frames, it's all
hidden. gRPC doesn't expose any of those details. The framework has already made all the
decisions on how to layer your RPC model on top of the protocol.
Betts
: I think that's a great callback to people who saw Christi Schneider's presentation, talking about
design for extensibility. She talked a lot of the same things without specifically mentioning it was
just APIs. It really is if you have some product that you're trying to adapt over time, how do you
version it? How do you document? How do you teach people about it? How do you get them to
adopt it?
McLarty
: On the theme of architecture, what's the difference between architecture and design? It could
be just architecture are those decisions you make that have long lasting implications. There are
things you can do upfront that will snooker you on creating landmines down the road. It's
definitely important to put that thought in.
Betts
: Michelle, there's a Q in GraphQL, but there's no C. Do commands not even work through
GraphQL? Is that something somebody else should be responsible for?
Garrett: I've honestly not heard this acronym before, so maybe you can tell me.
Betts
: You have a path where you go down and you write all of your queries against a read model. Like
Matt said, SQL Server was being slow, so you wrote materialized views, so they read faster, or
whatever you did, but that you don't write a document and read a document the same way.
GraphQL seems to be, I'm going to aggregate all my data together and I can ask all these
different questions, just give me this little bit of data. It's not meant for, please send a message
to the next person in the queue, or something like that.
McLarty
: I think it's interesting that you've got queries, mutations, and subscriptions as well. I've been
banging this drum around commands, queries, events, whatever you want to call them, like
there's these three different interaction patterns. Again, that goes back to the fact that maybe
these protocols aren't all that different. We're solving similar problems, and there's a unified,
conceptual view of the world that is expressed in all three.
Betts
: I know RPC is remote procedure call, it doesn't imply what you're doing. You can do whatever
you want.
Borysov
: Absolutely. It does not. You can easily define separate services, you can define a service to read
your data, and a separate service to mutate your data. You will have query service and command
service, they can be implemented by the same gRPC service, but those services are just
namespaces. If your consumer is read, thus they use your query service, if they're write, they
send commands using your command service.
Borysov
: If I have a rich UI that aggregates data from multiple sources, I'll go with GraphQL. I might end
up supporting two ideals but there's a price to pay. On the other hand, if I have a subset of
consumers who can't or don't want to use gRPC clients, I will go with REST.
An Option to GraphQL
Betts
: Michelle, if I said we couldn't just use GraphQL everywhere, who's your wingman?
Garrett: I'm going to pick REST as my wingwoman. Although I feel like REST and GraphQL are
pitted against each other. I'm sorry that I called it ugly earlier on. I think that they have a lot of
harmony together. They're often found together in real world implementations of GraphQL.
There are just so many REST APIs in the world and I don't think REST APIs are going to go
away. I think that wrapping a REST API in a GraphQL layer, but maintaining the underlying
REST API services is a really common pattern, and is a sweet spot for the two of them to work
together.
Betts
: I thought it might have been CORBA once again, coming back up.
References
GraphQL
gRPC
Protocol Buffers
Michelle Garrett
Michelle Garrett is a Software Engineer at Twitter, where she is part of the team building
Twitter's large scale GraphQL API. Prior to Twitter, Michelle worked on a GraphQL
implementation at Condé Nast, powering the international Vogue websites. Michelle is an
organiser of Node Girls, which provides free technical workshops in an effort to improve gender
diversity in the industry.
Show more
Show less
Matt McLarty
Matt McLarty is the Global Field CTO for MuleSoft, a Salesforce company. He works closely with
organizations to define digital strategies, as well as design and implement enterprise-grade API
and microservices solutions. An experienced software architect, Matt has worked extensively in
the field of integration and real-time data distribution. He is the co-author of the O'Reilly books
Microservice Architecture and Securing Microservice APIs, and co-host of the APIs Unplugged
podcast.
Show more
Show less
Alex Borysov
Alex is currently a senior software engineer at Netflix, where he is working on building a unified
global digital Studio that powers the effective production of Netflix content. Prior to joining
Netflix, Alex had designed, implemented, and run various World-scale distributed systems,
including ML infrastructure for payments fraud detection at Google; large-scale backends at
Nest; microservice architecture for world-leading social casino games; and core infrastructure
services for a unicorn startup.
Show more
Show less
QCon brings together the world's most innovative senior software engineers
across multiple domains to share their real-world implementation of emerging
trends and practices.
Find practical inspiration (not product pitches) from
software leaders deep in the trenches creating software, scaling architectures and
fine-tuning their technical leadership
to help you make the right decisions. Save
your spot now!
Previous podcasts
Liz Rice on Programming the Linux Kernel with eBPF, Cilium and Service Meshes
Tudor Gîrba on How Moldable Development Offers a Novel Way to Reason about
Systems