72. Generate Swagger/OpenAPI from Protobuf
title: “72. Generate Swagger/OpenAPI from Protobuf: A Step-by-Step Guide to Automating API Documentation” date: 2024-06-13 author: “Rahmat Adi Putra”
For many engineers, keeping API documentation up to date as the codebase evolves is a real challenge. Manually maintained documentation often becomes a source of outdated information. Fortunately, the Cloud Native world offers plenty of automation solutions. One of them: generating Swagger/OpenAPI specifications directly from Protocol Buffer (Protobuf) definitions. This article walks through how that process works, complete with flow diagrams, sample .proto code, plugin configuration, and simulated output.
Why Swagger/OpenAPI & Protobuf?
Protobuf is a high-impact data serialization format that serves as the backbone of communication in the gRPC ecosystem. Swagger/OpenAPI, on the other hand, has become the industry standard for documenting RESTful APIs. But when one team implements a service with gRPC (Protobuf) and the client team needs OpenAPI (Swagger) documentation, it is all too tempting to update two sources of truth manually — leaving a wide opening for inconsistency.
The solution: Generate OpenAPI automatically from Protobuf!
Automation Architecture: The Flow Diagram
Let’s clarify the workflow with the following flow diagram:
flowchart TD
A[.proto file] --> B[protoc compiler]
B --> C[protoc-gen-openapiv2 plugin]
C --> D[openapi v2 json/swagger.yaml]
In short:
- Define your API and messages in a
.protofile. - Compile it with
protocusing theprotoc-gen-openapiv2plugin. - The plugin transforms your Protobuf services and messages into a Swagger/OpenAPI specification file (YAML/JSON).
Case Study: A Simple gRPC Service
A sample .proto file:
1// service.proto
2syntax = "proto3";
3
4package greet;
5
6service Greeter {
7 rpc SayHello (HelloRequest) returns (HelloReply) {
8 option (google.api.http) = {
9 post: "/v1/hello"
10 body: "*"
11 };
12 }
13}
14
15message HelloRequest {
16 string name = 1;
17}
18
19message HelloReply {
20 string message = 1;
21}(google.api.http) option is essential for mapping a gRPC endpoint to REST.Required Toolchain
| Tool | Minimum Version | Description |
|---|---|---|
| protoc | 3.x | The main compiler for .proto files |
| protoc-gen-openapiv2 | Latest | Plugin that converts Proto -> OpenAPI |
| grpc-gateway | 2.x/3.x | Helps bridge gRPC <-> REST (optional) |
| Go (if building from source) | 1.18+ | To build the plugin from source |
Installing the Plugin: protoc-gen-openapiv2
How to Install
a. Download the Binary (Recommended for CI/CD)
1GO_TAG=$(curl -s https://api.github.com/repos/grpc-ecosystem/grpc-gateway/releases/latest | jq -r .tag_name)
2wget https://github.com/grpc-ecosystem/grpc-gateway/releases/download/${GO_TAG}/protoc-gen-openapiv2-${GO_TAG}-linux-x86_64
3chmod +x protoc-gen-openapiv2-${GO_TAG}-linux-x86_64
4sudo mv protoc-gen-openapiv2-${GO_TAG}-linux-x86_64 /usr/local/bin/protoc-gen-openapiv2b. Build from Source
1go install github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2@latest$GOPATH/bin.The Swagger/OpenAPI Generation Process
Suppose your folder structure looks like this:
1project/
2 ├── proto/
3 │ └── service.proto
4 └── gen/Run the following command to generate the OpenAPI file:
1protoc -I proto/ \
2 --openapiv2_out=gen/ \
3 --openapiv2_opt logtostderr=true \
4 proto/service.protoOnce the process runs smoothly, you’ll get a gen/service.swagger.json file (or .yaml if configured that way).
Simulated Output (Swagger Spec Snippet)
1{
2 "swagger": "2.0",
3 "info": {
4 "title": "Greet API",
5 "version": "1.0"
6 },
7 "paths": {
8 "/v1/hello": {
9 "post": {
10 "operationId": "SayHello",
11 "parameters": [
12 {
13 "name": "body",
14 "in": "body",
15 "schema": { "$ref": "#/definitions/greetHelloRequest" }
16 }
17 ],
18 "responses": {
19 "200": {
20 "description": "A successful response.",
21 "schema": { "$ref": "#/definitions/greetHelloReply" }
22 }
23 }
24 }
25 }
26 },
27 "definitions": {
28 "greetHelloRequest": {
29 "type": "object",
30 "properties": { "name": { "type": "string" } }
31 },
32 "greetHelloReply": {
33 "type": "object",
34 "properties": { "message": { "type": "string" } }
35 }
36 }
37}Customization & Advanced Tips
1. REST Mapping
For REST endpoints to be generated, the option (google.api.http) attribute is mandatory on every rpc. Without it, the paths in your Swagger/OpenAPI spec will be empty.
2. Additional Metadata
Swagger lets you add information such as Title, Version, Contact, and more:
1import "protoc-gen-openapiv2/options/annotations.proto";
2
3option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = {
4 info: {
5 title: "Greeter API";
6 version: "1.0";
7 contact: {
8 name: "API Team";
9 email: "api@example.com";
10 }
11 }
12};3. Multiple Proto Files
If your project consists of many .proto files, simply list them all in the protoc command and make sure the dependencies between files are wired up according to their imports.
Simulation Study: CI/CD Pipeline
The best automation usually lives in a CI/CD pipeline. Here’s a simulation of the pipeline stages:
graph TB
A[Push kode ke repo] --> B[Trigger CI]
B --> C[Generate code dari .proto]
C --> D[protoc-gen-openapiv2]
D --> E[swagger.json artifact]
E --> F{Deploy ke portal Dokumentasi?}
F -- Ya --> G[Publish ke Swagger UI]
F -- Tidak --> H[Simpan di artifact storage]
FAQ
Q: Do I have to use a gRPC Gateway/REST server?
No. The main goal of this generation is to obtain API documentation. However, if you want the service to be accessible via HTTP/REST, you’ll need to implement bridging with grpc-gateway.
Q: Which version of OpenAPI is generated?
The protoc-gen-openapiv2 plugin produces an OpenAPI v2 schema (Swagger 2.0). For OpenAPI v3, the community is currently developing a plugin — feel free to follow this issue
.
Q: Can I customize response codes?
Yes, by using custom options in the proto file, though it’s not as complete as a hand-written Swagger spec.
Conclusion
Automatically generating Swagger/OpenAPI documentation from Protobuf files is a robust solution for keeping your API definitions and their documentation in sync. With the protoc-gen-openapiv2 tool, this process can be integrated into your developer workflow — all the way into your CI/CD pipeline. The result? Happy developers, documentation that’s always up to date, and tighter collaboration between back-end and front-end teams.
It’s time to let your API documentation speak directly from your core code!
References: