RPC and Query-Based API Design
This is a continued blog post series. You can find the first post here.
The Remote Procedure Call (RPC ) style of API as well as query based style has existed for a long time. So the obvious question is what to choose between REST, RPC, GraphQL etc?
And also when to use multiple different styles in the same API. To keep things simple it would be natural to stick to one thing. This chapter tries to explain when to do what.
What Is an RPC-Based API?
An RPC API supports invoking functionality on the server side using a client side call. But how is that different from a REST invocation you could ask. After all both are request replies?
The short answer is that REST is resource oriented and that you have options like content negotiation, REL links, HATEOAS if you choose to use it. That means the coupling is weaker and the options for extensions and evolution is better.
RPC is more coupled
So the important take aways are that when going for the RPC style API you get tighter coupling but may gain other things like performance or with graph QL the option to shape the response. The tighter coupling leads to the other recommendation which is that RPC Style is more safe if you own both Client and server side.
With RPC You gain control but looses standardization
Browsers don’t support gRPC natively. So extra work might be required here. Also security protocols gets mentioned. So things worth considering when choosing between the various API styles.
RPC API Design Process
In the following 3 step design process for gRPC API (useful for other RPC style API’s as well). We take the API profiles created in chapter 6 as input and fill out a new Table.
Step 1: Identify RPC Operations
We Identify RPC Operations and add them to an operations column in the new table.
Step 2: Detail RPC Operations
Step 3: Document the API Design
Changing the RPC Implementation will Replace the API
This part of the chapter is ended by reminding of the closed coupling that exists with a RPC based API. If you change the code you probably change the API and the Client has to implement code changes too.
The API Design Process allows you to change your mind
Another point is that most of the design work was done in the initial chapters so most work can be reused in case you change your mind and want to go for a REST style implementation in stead.
Query Based API’S
This chapter is like a 2 in 1 combo. So we have the 2nd part to cover, which is query based API’s like ODATA and graph QL.
Query-based APIs offer robust query capabilities and response shaping. This off cause requires more work. But for larger API Products the Generic nature of REST can be accompanied with great query functionality using ODATA or Graph QL.
The Chapter mentions Microsoft office 365 API as an example of an API that is supported by ODATA.
Graph QL was built from the need to serve both web frontend as well as mobile clients. Response shaping and flexible query supports allows one API to serve different needs in granularity.
Advantages, Disadvantages and typical use cases
The big difference between Graph QL and REST is that requests gets tunneled trough one end point. This makes things like authorization, caching and rate limiting more tricky to implement. Therefore many enterprise’s has chosen to use standard REST API’s for different business capabilities while at the same time also providing specific Query API’s to unify or supplement their REST APIS.
A case for graph QL is when You have high amount of data that gets changed frequently. This could be a Content Management system. In this case the lack of built in caching in graph QL, becomes less important.
I will not repeat all the details about ODATA and Graph QL here. In stead lets jump straight to the Design Process for Query based API styles.
Query-Based API Design Process
Step 1: Designing Resource and Graph Structures
It makes sense to have a design step for designing the graph structure for a graph based API. Above we can see how the resources for the Book Store example are interlinked. If You have followed the design steps in previous chapters thoroughly this step could be as simple as just checking that the graph is correct.
The Graph will manifest itself in the types in the GraphQL Definition. For instance the BookSummary will have a child collection of authors.
"Summarizes a book that is stocked by the book store..."
type BookSummary {
"An internal identifier, separate from the ISBN, that identifies the book within the inventory"
bookId: String!
"The ISBN of the book"
isbn: String!
"The book title, e.g. A Practical Approach to API Design"
title: String!
authors: [BookAuthor!]
}
Step 2: Design Query and Mutation Operations
The interesting take away from his design step is the recommendation to
map graphQL queries to API profile operations marked as safe and mutations
to operations marked as idempotent and unsafe
So each operation gets marked with either Query or Mutation in the Operation Type column.
Step 3: Document the API Design
Another neat recommendation is the link to https://github.com/graphql/graphql-playground
Summary
This was an extensive chapter covering both RPC Style API’s and Query API’s.
Even though explaining details about these API styles took time and effort to cover, what remains left is that the design steps to follow are not something far away. The design steps presented here are quite simple and straight forward, which is good news. And the important thing is that most of the work has been done all ready in previous design steps, before branching out into specific API style implementations be it REST, RPC or Query API’s.