Build Quality Microservices and Apps
By: Jimmy Soh
Tags: Software Development, Startup, Technology, Software Engineering, Programming

Build Quality Microservices and Apps

Ensure governance by including these five elements in your requirements document

Photo by Gabrielle Henderson on Unsplash

Fragile apps and microservices are often the results of vague requirements, and developers left to their interpretation and devices.

A well written technical requirements document provides sufficient information to ensure IT governance and implementation consistency across teams. Proper governance leads to better product quality, increased efficiency through clarity, and improved stakeholder collaboration, e.g. testers.

Software quality should be ensured before the coding starts, and not wait for quality assurance (QA) to raise issues to fix—as it would slow down the entire delivery process.

In the following, I’ll share five attributes of good technical API/microservice specification that has served me well during my stint as a developer doing the implementation; and as a tech lead managing the governance and requirements.

#1: Short description and intended callers

Microservices are often designed and built based on bounded contexts. Each microservice at the data layer would be in charge of its own set of tables or documents within a database, e.g. products, users, etc. according to microservice design principles.

In the short description, specify the following:

Database/table names to query — prevent overlapping of queries and joins to other tables managed by other teams/services.

— prevent overlapping of queries and joins to other tables managed by other teams/services. Downstream microservices invoked — applies to logic layer or stateless microservices to communicate and manage dependencies.

With the above information specified, the developer can then communicate with the relevant database and microservice owners to align requirements and bridge implementation gaps.

#2: Microservice details and non-functional requirements

The seemingly minor details such as transport encryption protocols and response headers could potentially lead to deployment issues, e.g. certificate incompatibility, failing security tests, etc. especially in a high-security environment.

Therefore, it’s crucial to indicate such details in the requirements document:

Transport authentication/encryption — specify whether if it’s mutual TLS, HTTP/HTTPS, etc. so that the developer can manage the application configuration and certificates in the codebase.

— specify whether if it’s mutual TLS, HTTP/HTTPS, etc. so that the developer can manage the application configuration and certificates in the codebase. Microservice supported actions — indicate if the application is supporting GET/POST/PUT/DELETE requests to limit redundant exposure of endpoints.

— indicate if the application is supporting GET/POST/PUT/DELETE requests to limit redundant exposure of endpoints. Microservice response headers — ensure that appropriate response headers are returned from the microservice to avoid exposing details that would threaten security, e.g. server type, etc.

— ensure that appropriate response headers are returned from the microservice to avoid exposing details that would threaten security, e.g. server type, etc. Microservice endpoints and query params — provide examples of the specific endpoint pattern, e.g. https://[NAMESPACE_URL]/[SERVICE]/v1/data?{param}={value}, to standardise API endpoint designs.

By indicating such details, it allows the developer to build the application with basic security considerations and governance in place.

#3: Request and response details

The request and response details potentially make up the bulk of the document. The information would also likely be disseminated to other collaborators to assist with service designs, testing, etc.

The key elements to include in this section are:

Request headers — some optional yet important examples include UUID headers to facilitate request tracing and accept-language for localisation.

— some optional yet important examples include UUID headers to facilitate request tracing and accept-language for localisation. Request query parameters — with the attribute name(s), required/optional, data type, and a short description of the attribute.

— with the attribute name(s), required/optional, data type, and a short description of the attribute. Response body — include attribute names (e.g. status, status.code, data, data.uuid), data type, and a short description for the attribute.

I would recommend the above information to be presented in a table format to facilitate readability for non-technical stakeholders. The next section on sample requests/responses will cater to the technical stakeholders.

#4: Sample requests and responses

For certain stakeholders, merely providing the request and response description and attributes would not suffice. Having a sample output response in JSON format enables the reader to quickly contextualise and visualise the desired output of the service with “actual” data.

To facilitate clarity, include the following in the sample request/response section of the document:

Microservice action, URL and headers — a suggestion would be to imagine you’re querying the actual service via CURL and include the essential details.

— a suggestion would be to imagine you’re querying the actual service via CURL and include the essential details. Response with HTTP code — for each HTTP code(s), include the respective response payloads to ensure that errors are properly handled; this is especially essential for services deployed in a mesh architecture.

You can refer to a sample snippet below.

Image by Author

#5: HTTP and business response codes

Considering the high interdependency of services in a microservice architecture, errors would have to be properly handled with appropriate response codes to facilitate debugging and tracing. The list of response codes also helps with testing of the microservice application.

Things to include:

HTTP response codes — details such as code number (403), name (Forbidden), type (Client Error), description (Invalid authorisation credentials).

— details such as code number (403), name (Forbidden), type (Client Error), description (Invalid authorisation credentials). Business response codes — include code number (8989), scenario (access token expired), description (the token is more than one day old).

In most cases, the solution architect/lead would have a list of error codes established during the solution design phase to reference against and standardise.