fankao / eStore

Sample Ecommerce application to practice Modern API Specification and Microservices with Spring Boot inspired on https://github.com/PacktPublishing/Modern-API-Development-with-Spring-and-Spring-Boot
0 stars 0 forks source link

API Specifications #1

Closed fankao closed 2 years ago

fankao commented 2 years ago

Using AOS to design and generate API template Start to create a Spring project from scratch using Spring Initializr (https://start.spring.io/) with the following options: • Project: Gradle • Language: Java • Spring Boot: 2.3.5.RELEASE • Project metadata with your preferred values • Packaging: JarAdded • Java: 15 (You can change it to 14 in the build.gradle file later.) • Dependencies: 'org.springframework.boot:spring-boot-starterweb'(Spring Web in Spring Initializer) Once you open the project in your favorite IDE (IntelliJ, Eclipse, or NetBeans), you can add the following extra dependencies required for OpenAPI support under dependencies in the build.gradle file:

swaggerCodegen 'org.openapitools:openapi-generator-cli:4.3.1'
compileOnly 'io.swagger:swagger-annotations:1.6.2'
compileOnly 'org.springframework.boot:spring-boot-startervalidation'
compileOnly 'org.openapitools:jackson-databind-nullable:0.2.1'
implementation 'com.fasterxml.jackson.dataformat:jacksondataformat-xml'
implementation 'org.springframework.boot:spring-boot-starterhateoas'

How to configure AOS API: https://github.com/PacktPublishing/Modern-API-Development-with-Spring-and-Spring-Boot/blob/main/Chapter03/src/main/resources/api/.openapi-generator-ignore https://github.com/PacktPublishing/Modern-API-Development-with-Spring-and-Spring-Boot/blob/main/Chapter03/src/main/resources/api/config.json https://github.com/PacktPublishing/Modern-API-Development-with-Spring-and-Spring-Boot/blob/main/Chapter03/src/main/resources/api/openapi.yaml

fankao commented 2 years ago

Step 1 – adding the Gradle plugin To make use of the OpenAPI Generator CLI tool, you can add the Swagger Gradle plugin under plugins {} in build.gradle as shown:

plugins {
…
…
id 'org.hidetake.swagger.generator' version '2.18.2'
}
fankao commented 2 years ago

Step 2 – defining the OpenAPI config for code generation You need certain configurations, such as what model and API package names OpenAPI Generator's CLI should use, or the library it should use for generating the REST interfaces or date/time-related objects. All these and other configurations can be defined in config.json (/src/main/resources/api/config.json):

{
"library": "spring-mvc",
"dateLibrary": "java8",
"hideGenerationTimestamp": true,
"modelPackage": "com.packt.modern.api.model",
"apiPackage": "com.packt.modern.api",
"invokerPackage": "com.packt.modern.api",
"serializableModel": true,
"useTags": true,
"useGzipFeature" : true,
"hateoas": true,
"withXml": true,
"importMappings": {
"Link": "org.springframework.hateoas.Link"
}
}
fankao commented 2 years ago

Step 3 – defining the OpenAPI Generator ignore file You can also add a .gitignore-like file to ignore certain code you don't want to generate. Add the following line of code to the file (/src/main/resources/api/. openapi-generator-ignore): **/*Controller.java We don't want to generate controllers. After its addition, only API interfaces and models will be generated. We'll add controllers manually.

fankao commented 2 years ago

Step 4 – defining a swaggerSources task in the Gradle build file Now, let's add the logic to the swaggerSources task in the build.gradle file:

swaggerSources {
    def typeMappings = 'URI=URI'
    def importMappings = 'URI=java.net.URI'
    eStore {
        def apiYaml = "${rootDir}/src/main/resources/api/openapi.yaml"
        def configJson = "${rootDir}/ src / main / resources / api/config.json"
        inputFile = file(apiYaml)
        def ignoreFile = file("${rootDir}/ src / main / resources / api /.openapi-generator-ignore")
        code {
            language = 'spring'
            configFile = file(configJson)
            rawOptions = ['--ignore-file-override', ignoreFile,
                          '--type-mappings',
                          typeMappings, '--import-mappings', importMappings] as
                    List<String>
            components = [models: true, apis: true, supportingFiles:
                    'ApiUtil.java']
            / / depends On validation // Should be uncommented once
            //plugin starts supporting OA 3 validation
        }
    }
}

Here, we have defined eStore (user-defined name) that contains inputFile pointing to the location of the openapi.yaml file. After defining the input, the generator needs to produce the output, which is configured in code. We have defined language (it supports various languages), configFile pointing to config.json, rawOptions (contains the type and import mappings), and components in the code block. Aside from language, all are optional. We just want to generate models and APIs. You can generate other files too, such as clients or test files. ApiUtil.java is required in the generated API interface else it will give a compilation error during build time; therefore, it is added in components.

fankao commented 2 years ago

Step 5 – adding swaggerSources to the compileJava task dependency Next, we need to add swaggerSources to the compileJava task as a dependent task. It points to the code block defined under eStore: compileJava.dependsOn swaggerSources.eStore.code

fankao commented 2 years ago

Step 6 – adding the generated source code to Gradle sourceSets We also need to add the generated source code and resources to sourceSets. This makes the generated source code and resources available for development and build:

sourceSets.main.java.srcDir "${swaggerSources.eStore.code.outputDir}/src/main/java"
sourceSets.main.resources.srcDir "${swaggerSources.eStore.code.outputDir}/src/main/resources"
fankao commented 2 years ago

Step 7 – running the build for generating, compiling, and building the code The last step is to execute the build. Make sure you have an executable Java code in the build path. The Java version should match the version defined in the property of build. gradle (sourceCompatibility = '1.14') or in the IDE settings: $ gradlew clean build

image