{{announcement.body}}
{{announcement.title}}

Comparing OpenAPI With gRPC

DZone 's Guide to

Comparing OpenAPI With gRPC

OpenAPI is a great choice due to its interoperability. On the other hand, gRPC offers a better performance. Luckily, you don't have to choose one or the other.

· Integration Zone ·
Free Resource

Are you still coding your API client libraries by hand? Is your manually maintained API documentation drifting away from what was actually implemented? You may be interested in reviewing the two popular technologies that solve this problem. In this article, we are going to look at OpenAPI and gRPC side-by-side.

Both OpenAPI and gRPC are communication technologies very much needed in today's world of microservices applications. They allow you to describe your APIs using a formal language. This description then serves as a source of truth from which you can generate the client and server code and API documentation. As there are two viable alternatives, the question comes down to which one is going to work better for you. As I was trying to answer the same question, I did some research on the Internet and came up with a comparison table. I didn't include every single detail; however, this table could perhaps be a good starting point for you:

Criteria

OpenAPI

gRPC

Origins

OpenAPI evolved from the Swagger project. Swagger started out as a specification for documenting RESTful APIs. Later on, tools to generate client and server code and generating of test cases were added. While the original Swagger Specification was donated to the Linux Foundation and renamed the OpenAPI, Swagger remains one of the most widely used open-source toolsets for developing OpenAPIs.

gRPC was originally developed at Google. Later on, it was donated to Cloud Native Computing Foundation.

Communication protocol

OpenAPI uses HTTP/1.1 protocol for transport. For the data representation, JSON is generally assumed.

gRPC uses HTTP/2 protocol for transport and Protocol Buffers as a serialization format.

API description format

Developers describe their APIs using JSON or YAML documents that follow the OpenAPI Specification schema. You can find a large archive of sample OpenAPI descriptions at apis.guru/openapi-directory.

APIs are described using .proto files written in a Protocol Buffer Language.

Description style

REST APIs are described using HTTP verbs and URIs. Each URI represents a resource in your system, and the HTTP verbs represent actions you take on your resources.

REST APIs use HTTP status codes to signalize the results of the operation invocations. As the HTTP status codes were primarily meant to convey the results of the transport operations, the mapping of status codes to the results of your API functions may be a bit loose.

With gRPC, you can describe your API in terms of methods or procedures. However, if a lot of methods are added over time, the end result can be a complex and confusing API due to the fact that developers must understand what each method does individually. Instead, Google suggests to use a resource-oriented design which applies the REST design principles to gRPC. This results in more comprehensible APIs. Also, if you intend to transcode HTTP/JSON API into gRPC, you will greatly benefit from a gRPC API designed using the resource-oriented approach.

gRPC offers a set of error codes that are well suited to describe the outcome of API operations.


Client and server code generation

There are several tools for generating code based on the OpenAPI description. The most widely used code generation project is Swagger Codegen. Other projects include AutoRest and oas-nodegen.

gRPC comes with a modular code generator called protoc. Each supported language is implemented as a separate plugin. The code generator was part of the gRPC project from its inception.

Interactive documentation

Swagger UI is a great toogRPCl to visualize your API and execute test requests against your API.

prototools and protoc-gen-doc can generate documentation based on your .proto files.

Tooling

Swagger Tools, curl, Postman, web browsers, tcpdump, Wireshark.

Awesome gRPC, gRPCurl. At the time of this writing, Wireshark supports gRPC only partially.

Performance

HTTP/1.1 protocol is a request/response protocol. When sending multiple requests over a single TCP connection, the next request can only be sent after the response to the previous request was received. This would normally result in a poor performance especially on the connections with higher latency. To increase the performance, HTTP client opens multiple TCP connections to a single server and sends multiple HTTP requests in parallel. New connections are opened as they are needed. As establishing a new TCP connection is associated with a cost, clients implement connection pooling to reuse the existing TCP connections. Remember to tune the clients connection pool to achieve good performance. 

Some HTTP clients/servers may support HTTP/1.1 pipelining. Each HTTP request over the TCP connection may be made immediately without waiting for the previous request's response to return. As request responses must be returned in the order requested, this is prone to head of line blocking. 

HTTP/1.1 is a text-based protocol and JSON is a text-based serialization format which hurts the performance.

By default HTTP/2 client opens a single TCP connection to the server and multiplexes multiple requests on this connection. Requests and responses are split into chunks and can be returned in an intermingled fashion. This prevents the head of line blocking that HTTP/1.1 pipelining may suffer from. In addition to that, the client can open multiple HTTP/2 connections to a single server and implement connection pooling. However, it is common to use a single TCP connection only. 

HTTP/2 is a binary protocol. Also, according to this article by Tim Burks of Google, the Protocol Buffers binary format can be orders of magnitude faster to read than corresponding JSON serializations. 

Overall, gRPC offers a better performance than OpenAPI.

Summary

OpenAPI offers a great interoperability due to leveraging widely used HTTP/1.1 protocol and the JSON format. There is a great amount of tools available that will work with OpenAPI-based interfaces.

If you are looking for maximum performance, gRPC is a great choice for you. Also, HTTP/2 protocol is gradually gaining market share. Why not start using it today?

Where to Go From Here

The comparison table in the previous section highlights only the basic characteristics of OpenAPI and gRPC. I constructed the table based on many great articles that I found on the web. If you are interested in further details on how OpenAPI and gRPC compare, I recommend you visit the following resources:

Combining OpenAPI and gRPC

Do you have to use either OpenAPI or gRPC? If you like the awesome performance offered by gRPC but still need to provide REST interfaces to the external third-party clients, there is a solution for you. You can leverage one of the proxies (Envoy, grpc-gateway) that can transcode the REST interface into gRPC. If you design your gRPC interfaces in a resource-oriented fashion the transcoding process is straight forward. The resulting system architecture may look like this:

The third-party REST client talks to the proxy using HTTP/JSON. Client requests are transcoded on-the-fly into gRPC requests. After the requests are processed, the resulting responses are transcoded from gRPC back to HTTP/JSON and delivered to the client.

Conclusion

In this post, we compared the basic characteristics of OpenAPI and gRPC. OpenAPI is a great choice due to its interoperability. On the other hand, gRPC offers a better performance. However, you don't have to choose one or the other. You can happily combine both technologies in a single system.

I hope you enjoyed this article. If you are looking into OpenAPI or gRPC, I would be happy to hear about your thoughts. Please, feel free to leave your comments in the comment section below.

Topics:
microservice communication ,grpc ,openapi

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}