View on GitHub

Povio Engineering Guidelines

These are guidelines for the technologies we are using.

Backend Development with Spring

Spring Logo

Table of Contents

General Notes

The purpose of this section is to give guidelines/best practices for design and implementation of a typical backend REST API. A typical REST API exposes HTTP endpoints over HTTP and uses JSON requests and responses. It typically uses a relational database and integrates with some other 3rd party APIs.

These guidelines are divided into 2 parts. The first section concentrates on the best practices of backend REST API development. The second section contains Spring Boot specifics on how to effectively implement the principles defined in section one with the Spring Boot framework and Java programming language.

Backend Development

API-First Approach

The API-first approach as an alternative to the code-first approach states that one should first define the API of an application and get a buy-in of all stakeholders. Only after that can the application be developed in several parallel streams. Main benefits of API-first approach are:

The output of the API First Design phase should be an OpenAPI Specification document. This document can be designed using Swagger Editor (also available as a docker image). Once it is committed, other teams (frontend, QA) can start using it. Since the API specification represents a contract, several teams can work in parallel. Every change to the specification should be clearly communicated to other team. Backend server code and also client side code can be generated based on the OpenAPI Specification.

API specification is the deployable artifact.

API Design

There are several schools of API design. Whichever you choose, make sure that your API design is consistent. Most of them agree on the following:

Please comply with those agreed upon principles.

References:

Architecture Best Practices

As a backend developer you are responsible for the architecture of the backend service you are developing. There are some generally agreed upon best practices that should be familiar with and which you should incorporate into your service. Those are:

Backend API with Spring Boot

Spring Boot is a backend framework that allows you to develop production-grade, stand-alone applications. As Spring Boot is based on the Java Spring framework, it inherits most Java features and with it the complete JVM ecosystem (3rd party libs). The app runs on top of a multi-threaded web application server like Tomcat or Jetty.

One of the main pros of using Spring Boot is the Java community which is mature and fully grown. The community is vast and experienced. When you choose Spring Boot, you indirectly choose long-term support and maintainability for your application.

Spring Boot has already solved most of the common challenges a modern cloud native application is facing. Therefore, a developer does not need to reinvent the wheel. Instead, they use one of the ready-made Spring Boot starters or 3rd party library that solves the problem.

Best Practice Project

A good source code tells more than 1000 words. Therefore, we maintain a best practice project for a Spring Boot backend development. It is available at: spring-boot-template. It is an implementation of the pet clinic project REST API, and it follows the best practices described in this page. Please check out the different branches that contain approaches to a problem solution.

Language

Java is still the default programming language for Spring Boot application development. Make sure you use one of the newer versions and update it on a regular basis. Kotlin is another alternative that is fully supported by Spring Boot. At this moment Java is still preferred over Kotlin. How to write quality Java code? The answer for this is beyond this section. The book Effective Java is a great resource with generally agreed upon Java good practices. Here is a great summary of the book.

IDE

IntelliJ Ultimate Edition is the preferred IDE for Spring Boot application development. Import and apply the style guide that is defined by the project. If there is no project style guide, use the IntelliJ default style guide.

Some recommended plugins:

Project Creation

Head over to Spring Initializr to get a pom with the dependencies that most suit your project. When adding new dependencies, Spring Initializr should be you preferred choice.

Project Structure

It is recommended that the Spring Boot project is Maven based. Gradle is a valid alternative. Reasons for choosing Maven over Gradle:

Code Structure

Write your code as if it were Lego blocks. This means that small units with clearly defined responsibilities and a well-designed API can be combined into higher level units. The coupling between those units should be as loose as possible.

Use Maven submodules to be able to reuse some parts of the code in other projects. A submodule can easily be extracted into its own library.

When organizing your code into packages, follow the package by feature approach. Keep the packages small (7 +- 2 classes).

For smaller projects spring 3 layer architecture is recommended. But if you want to experiment with some more advanced architecture like clean (hexagonal) architecture you are welcome to give it a try and share the experience. Spring Web App Architecture

It is highly recommended that you split the data model used on the web from the database model. This prevents accidentally breaking the API and enables more flexibility with designing web (DTO) model and the database model. The cost of using a mapper object is not too high. A manual mapping implementation is recommended over mapping tools.

When you write business logic (service layer), think of it like creating a factory wih conveyor belts. The domain objects are the resources that are processed in the service pipelines. Each service is like a work station that manipulates/creates new domain objects. With such mindset the design of the API is much easier. The domain objects only need to know about its state. When considering creating a new object vs changing the existing one, pick a new object because immutable objects are much easier to work with.

Database Integration

Some good practices when working with a DB:

Database Migration

We prefer Flyway over Liquibase as database migration tools.

Migration scripts have to be written in SQL and migrations should be done with Flyway. Using Liquibase on projects, due to our experience, can cause deadlock issues. One good example of how to migrate a database with Flyway is this guide.

We also have to decide which tool to use, meaning which tool will bring us faster migration with as little as possible additional load and recovery time. Also, migration changesets should be written in a backward-compatible way. Cleanup of old structures should happen in the next release.

Logging

Exception Handling

Exception handling in Spring is nicely explained in this article.

Highlights:

Security

Spring security is a broad and complex topic. It takes time to master it. This article explains it in an effective and developer friendly way. Use the spring boot security starter. If JWT authentication is good enough for the project, then implement it. One good example how to implement JWT token generation and authentication is this guide.

OAuth2 related guidelines are still a WIP. Check also OAuth2 reference

Another aspect of security is handling sensitive data. Make sure sensitive user data such as passwords are hashed and data such as bank account numbers are encrypted. When logging, make sure sensitive data is masked.

A security review is recommended before the project is shipped.

3rd Party API Integration

Some best practices when integrating with a 3rd party REST API:

Testing

Application Configuration

Environment specific configuration properties should be defined with SPRING_APPLICATION_JSON env variable or java system property

  java -Dspring.application.json='{"name":"test"}' -jar myapp.jar

use configuration properties to enable/disable some functionalities instead of @Profile

Open Source Attribution

We are developing proprietary software. In it we depend on open source libraries. Therefore, we are not allowed to use any open source libraries that have a copyleft license. We also have to give attribution (i.e. mention the license of the library we depend on in the license folder). To give appropriate attribution do the following:

CI/CD

Work in progress: