7 Tips When Working with grpc-gateway’s Swagger Support.

Jim Geoshua Bactad
Golang Diary
Published in
4 min readFeb 1, 2020
Swagger Logo by SMARTBEAR ©.

While working with gRPC framework and the grpc-gateway library to develop a gRPC application with REST support and swagger integration, I realized that despite all example codes in the grpc-gateway repository, it still takes a lot of time to setup and have a working application.

In this post, I will list some of the things I discovered while working with the two libraries that could help you speed up the integration of swagger with your gRPC application.

1. Merge swagger files into one

When writing a large protobuf definition, it makes sense to break down the definitions into multiple files. This helps with readability and better organization of code, generated code will be breakdown into multiple files, and so are the swagger files. This will require you to serve all the swagger files in multiple endpoints and feeding them to Swagger-UI. If you do not prefer this behavior, you can pass allow-merge=true to protoc-gen-swagger during the generation of code to merge the swagger files into one file. This will generate a file called apidocs.swagger.json by default. And, if you want to change the generated file name, pass merge_file_name=yourfilename to the command.

Executing this command will generate a file named myawesomeapi.swagger.json.

2. Swagger options in a separate file

If you use Goland and you are like me who lets the IDE formats everything, you will be annoyed the moment you want to set grpc.gateway.protoc_gen_swagger.option.openapiv2_swagger to set additional OpenAPI options. The moment you format your proto file, the definition will be messed up. This is annoying because the protobuf generator will throw an error.

Below is a sample desired and formatted proto files.

The first snippet is the expected protobuf code, the second is the pasted version, don’t ask for the formatted protobuf, it is even worst.

3. Set fields to read-only

Most of the time, you want the fields in your API to be updatable. But there are certain fields like a resource id which doesn’t make sense to be updated. Fortunately, just by adding a comment // Output only.in the field of the protobuf message will mark the field as read-only.

Example proto with the generated swagger definition.

4. Filter values to update

In gRPC, there is no null value, instead, if a value is undefined, it defaults to an empty value, i.e. string="" or int=0. This is quite problematic because it will be difficult to identify if the value is being set empty or is not defined in the request. A way to solve this is to list the property names that are set in the request. This needs to be set by the sender of the request though. grpc-gateway takes this one step further by automatically detecting the property names from the payload of the request and automatically sending the list.

The only requirement here is that the protobuf request message should have a field update_mask with type and the request should be a PATCH request.

Using update_mask for PATCH request.

One important thing to know is if the request is aPUT request, the update_mask field will not be automatically populated. For more information about field masks, please see the it’s godoc.

5. Inject URL path values to protobuf message

This one is useful if you want to make your protobuf message definitions neat. In a typical REST implementation, updating resources requires the id of the resource to be passed in the URL. For example /v1/product/1 , luckily this was thought out by the creators of grpc-gateway by allowing URL parameters and mapping them to protobuf message fields.

Injecting URL query parameters to protobuf message.

The field awesome_name.id will automatically be set based on the value of the URL path.

6. Override JSON field names

The grpc-gateway swagger generator uses camel-case by default when generating swagger definitions. If you want to use snake-case instead, you can set the protobuf built-in json_name field option to the desired property name.

Overriding JSON property name using json_name option.

7. Use the full package name in swagger definitions

When you are merging the generated swagger files into one and you have more than one package, it is sometimes difficult to identify which message belongs to which package. To solve this, the swagger generator offers the option to include the full package name in the generated swagger definitions. To do this, you need to pass the option fqn_for_swagger_name=true when executing the generator.

Include full service name in swagger definitions.

Conclusion

The grpc-gateway’s capability to generate swagger files is an awesome feature that helps in generating beautiful documentation as well as an easy way to test your application’s API. After reading this post, I hope that you’ll be more comfortable using the library.

If you have comments or suggestions, please feel free to write in the comment section.

--

--