One of the first things we want to do with a microservice is document the contact for any potential users.
We have to publicly document our shared APIs
Every organization will have its own way of doing that, but one common approach is to use Open API as a documenting tool for the API itself.
The Open API standard
This standard should be well-known to any microservice developer, and I won't go into the history or the background. As a demonstration - I'll provide an example of an open API 3.0 implementation. Every org is different through - some don't want to see this code in the final compilation, some want to keep it separate from the code. This is an example where the API documentation is in the code and the runtime can be turned on or off based on a feature toggle.
First lets go through the steps we take to add open api to the sendgrid mailer.
/* the bean annotation */ @Bean/* the feature flag */ @ConditionalOnProperty(prefix ="feature.toggle", name ="openapi", havingValue="true")/* the Bean */publicOpenAPIcustomOpenAPI() {returnnewOpenAPI().components(newComponents()).info(newInfo().title("Sendgrid Mailer API").description("Simple microservice tutorial")); }
Add Endpoint Annotations
What we are doing is annotating the API endpoints and objects in the code itself.
For each endpoint we add the documentation for that endpoint as a set of annotations
@Operation - to identify the endpoint
@ApiResponses - to document what kind of responses we should expect to get
@Parameter - to document the inputs to the endpoint
example for the handleRequest() endpoint
@Operation(summary ="Send a new email", description ="See the Sendgrid documentation for the Response object", tags = { "send" })@ApiResponses(value = { @ApiResponse(responseCode ="200", description ="Request was processed (the actual return code is in the Response::statusCode") })@PostMapping(value ="/send", consumes = { "application/json" })publicResponseEntity<Response>handleRequest( @Parameter( description="Simple Email request", required=true, schema=@Schema(implementation =SendgridRequest.class)) @RequestBodyString mailRequest) {...}
Optionally add Schema Annotations
Its optional to update the data pojos - the Open API documentation will automatically find and document them. For example - the SendGrid Response object is documented even though it's not in our source code. But if we want to communicate a little more than just names and storage types -- we can do that with annotations.
example annotations for the SendgridRequest class
@Data@AllArgsConstructor@NoArgsConstructor@BuilderpublicclassSendgridRequest { @Schema(description ="Sender name", required =true)String senderName; @Schema(description ="Email address of the sender", example ="me@gmail.com", required =true) @EmailString fromAddress; @Schema(description ="Email address of the recipient", example ="you@gmail.com", required =true) @EmailString toAddress; @Schema(description ="Email subject", required =true) @NotBlankString subject; @Schema(description ="Email body", required =false)String content; @Schema(description ="Properties that Sendgrid will return to us in event activity", required =false)privateMap<String,String> customArgs;}
Open API JSON Definition
The Specification
Once we make the changes above - we can start up our service and call:
GET /v2/api-docs HTTP/1.1
Host: localhost:5000
Content-Type: application/json