Join GitHub today
GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.Sign up
GitHub is where the world builds software
Millions of developers and companies build, ship, and maintain their software on GitHub — the largest and most advanced development platform in the world.
Proposal: Expand OpenAPI to include RPC APIs #801
The OpenAPI 2.0 Specification states that its goal is “to define a standard, language-agnostic interface to REST APIs”. REST is an extremely popular style for implementing APIs that run over HTTP and related protocols (HTTPS, HTTP/2, QUIC). But other transport mechanisms are common and APIs are often defined in ways that correspond to procedure calls. In some ways, procedure calls are more fundamental, as REST APIs are often implemented by systems that convert REST requests into procedure calls.
At times it is desirable to use remote procedure calls (RPCs) as the primary form of an API. RPC systems allow expression of semantics that go outside the range of the HTTP verbs used by REST. RPC systems map naturally to the function calls that are used to implement most software systems, and RPC provides a design pattern that can be use to guide system implementations. The RPC abstraction is also much older than REST, and new systems such as gRPC and Thrift show its enduring usefulness.
With this in mind, we think it would be beneficial to expand the scope of the OpenAPI specification to include remote procedure call semantics. Here we propose an expanded specification that builds on our experience using RPCs to connect very large distributed systems while being general enough to apply to a broad range of variations.
We give special consideration to the Protocol Buffer message representation. At Google, Protocol Buffers are used to send and receive tens of billions of messages each second. Protocol Buffers are also used for messages in the open-source gRPC framework and other more specialized RPC frameworks   .
Protocol Buffers are typically represented in a binary form, and the latest version (proto3) also allows mapping to representations in JSON and YAML formats. Messages can be generally treated as collections of typed fields, just as they are in other serialization formats including Thrift, Avro, and Cap’n Proto. Thus message description can be treated similarly for all of these representations, including the JSON and YAML that OpenAPI uses to describe request and response objects.
Protocol Buffer interfaces are defined using a special description language (
Remote procedure calls are described in terms of the messages that they send and receive. Messages contain fields that have names, types, and other attributes, often including an integer field number that is used in message serialization.
In RPC terminology, "Services" are collections of remote procedure calls that send and receive messages. Each call has a single input and output message, and some RPC implementations will allow input and output messages to be streamed in a single call. Thus each remote procedure call is described by its name, input type, output type, and whether or not the input and output messages are streamed.
Here we show an example
Open API Representation
RPC messages are described in the OpenAPI
Properties of a message correspond to fields in a protocol buffer message.
Here we show an example OpenAPI representation of the messages in the Bookstore API.
Services are a distinct new entity that we represent using the
Services are described by their name and the procedures they contain. Procedures are described by the objects they accept and return. Streamed values are indicated with
Here is an example OpenAPI representation of the services in the Bookstore API (in this case, a single service named "Bookstore").
Our intent is to make it possible to write tools that convert back-and-forth between
OpenAPI representations are more verbose than
Types in OpenAPI and Protocol Buffers
Protocol Buffers contain many finely-differentiated scalar types, while the OpenAPI spec uses general types such as number and integer. In OpenAPI, an additional
In the above table, the
Gaps between OpenAPI and Protocol Buffers
There are some Protocol Buffer features that aren’t yet covered by this proposal. Gaps that are significant and unresolved may be addressed in future proposals.
Default field values could be represented with the existing OpenAPI
Enumerations are represented with strings in OpenAPI and integers in
Here we omit further discussion of maps, leaving it as a more general question about the OpenAPI Specification.
Extensions are defined in
Packages and API Versions
API Versions are commonly indicated by the last segment in a package name (segments are separated by periods). When the last segment looks like a version name (beginning with a 'v' and following with a possibly-dotted number), it is used as the version name. We omit this convention from this proposal and leave the representation of API versions to the existing
If we look at RPC APIs over JSON/YAML, I feel the
E.g. if we look at JSON RPC 2.0 for instance, requests have two main formats.
Where a large collection of different methods exist.
The responses in JSON RPC are of format:
Where the schema of the result (and in principal error) are generally determined by the request method.
At least for the first variant, there is no problem describing this as a set of
The only missing feature for a correct implementation with this approach, is to be able to provide a similar discriminator object for the response type that instead of switching on a field in the response payload, switches on a field at a particular path in the request (A discriminator object for batch requests is probably not something we could pull of though).
I am not stating that this is the best way of documenting a RPC API.
But I think it's important that the scope should be to describe the HTTP Protocol for the RPC API, and not the RPC API in general (which could be protocol agnostic).