Practise DDD with Swagger API Contract

Background

Owing to the microservice of the software development direction, Domain Driven Design (DDD) is the good pattern for mapping business domain concepts into microservice. Different developers have different opinions to implement, this blog is a kind of our practice with DDD, Spring boot, Swagger API in a simple and effective way.

Architecture

A typical enterprise application architecture consists of the following four conceptual layers: https://www.infoq.com/articles/ddd-in-practice

  • User Interface (Presentation Layer): Responsible for presenting information to the user and interpreting user commands.
  • Application Layer: This layer coordinates the application activity. It doesn’t contain any business logic. It does not hold the state of business objects, but it can hold the state of an application task’s progress.
  • Domain Layer: This layer contains information about the business domain. The state of business objects is held here. Persistence of the business objects and possibly their state is delegated to the infrastructure layer.
  • Infrastructure Layer: This layer acts as a supporting library for all the other layers. It provides communication between layers, implements persistence for business objects, contains supporting libraries for the user interface layer, etc.

Screen Shot 2018-08-02 at 15.00.48.png

we prefer to use package structure instead of maven model structure, there are some experiences,

  • one micro service is an isolated business logic module, share java API module with mircoservice is coupling tightly
  • we release 1 mircroservice almost includes all the maven module,  there is no frequency that releases update API, Implementation, common or infra maven module separately.
  • keep simple, more modules inside, more version maintaining job in nexus and developer understanding

we prefer to API contract(Swagger.yml)  instead of Hard Code of java Interface, there are some practices.

  • Industry standard contract definition in REST or gRpc
  • Swagger.yml can auto-generate interface, DTO, Documentation to improve the efficiency of developing, https://github.com/swagger-api/swagger-codegen
  • Spring boot Rest interface is perfectly matched with swagger.yml code generate.
  • With the swagger contract, communication with another language system easily, like javascript or etc
  • Big cloud platforms like AWS, Google, kubernetes can deploy API gateway pattern with swagger.yml directly.

Spring Swagger Code Generation

Swagger provides some easy tools in https://github.com/swagger-api/swagger-codegen. there are 2 steps to use it

  • swagger dependency in your maven pom.xml
<plugin>
    <groupId>io.swagger</groupId>
    <artifactId>swagger-codegen-maven-plugin</artifactId>
    <version>${dep.plugin.swagger-codegen.version}</version>
    <configuration>
        <inputSpec>src/main/resources/push.swagger.yml</inputSpec>
        <modelPackage>com.xxx.services.push.notification.view</modelPackage>
        <apiPackage>com.xxx.services.push.notification.view.api</apiPackage>
        <language>spring</language>
        <output>.</output>
        <generateApis>true</generateApis>
        <generateModelDocumentation>false</generateModelDocumentation>
        <generateSupportingFiles>false</generateSupportingFiles>
        <configOptions>
            <delegatePattern>false</delegatePattern>
            <sourceFolder>src/main/java</sourceFolder>
            <hideGenerationTimestamp>true</hideGenerationTimestamp>
            <useBeanValidation>false</useBeanValidation>
            <java8>false</java8>
        </configOptions>
    </configuration>
</plugin>

Plugin Configuration,  inputspec is your swagger.yml location

  • inputSpec is swagger file
  • apipackage is api package
  • using spring the language is important
  • Prefer to use pure java interface instead of java 8 default interface implementation, disable java8
<plugin>
    <groupId>io.swagger</groupId>
    <artifactId>swagger-codegen-maven-plugin</artifactId>
    <version>${dep.plugin.swagger-codegen.version}</version>
    <configuration>
        <inputSpec>src/main/resources/push.swagger.yml</inputSpec>
        <modelPackage>com.xxx.services.push.notification.view</modelPackage>
        <apiPackage>com.xxx.services.push.notification.view.api</apiPackage>
        <language>spring</language>
        <output>.</output>
        <generateApis>true</generateApis>
        <generateModelDocumentation>false</generateModelDocumentation>
        <generateSupportingFiles>false</generateSupportingFiles>
        <configOptions>
            <delegatePattern>false</delegatePattern>
            <sourceFolder>src/main/java</sourceFolder>
            <hideGenerationTimestamp>true</hideGenerationTimestamp>
            <useBeanValidation>false</useBeanValidation>
            <java8>false</java8>
        </configOptions>
    </configuration>
</plugin>

Inheritance of  API Contact

Screen Shot 2018-08-02 at 15.13.48.png

Summary

The main target is not discussing the DDD in deeply, it is a more effective practice to implement a full backend and frontend project. it was used in push notification(java backend) and swipe game(typescript frontend) with this direction.

Reduce over 80% of the duplicated API, Class definition, name conversation work, only DTO to Model Mapping is the heavy tasks in programming. Let developers focus on the Business Service logic with this scaffold Cross-language with contract easily.

 

Posted in

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.