Automatic code generation from a Swagger definition for a REST API

In this article I will be explaining in some simple steps how to auto generate Java code for a REST API by using the popular open source software framework Swagger. If I’m to give you a brief idea about Swagger, I can simply say it as a software which supports to develop, interact and document APIs. Swagger codegen is a tool used by thousands of developers worldwide to generate API client libraries, server stubs and documentation automatically given a Swagger definition.

Step 01:

The first step is to write Swagger API specification using the swagger editor. Swagger specification can be written either in YAML or JSON. I will be using YAML. It is somewhat tricky task to write the specification properly. So make sure to go through the Swagger documentation carefully.

Here is a sample Swagger definition for you to get an idea. I have defined a HTTP POST method to send member details to a server for member registration. Member details are to be enclosed in the body of the request message in JSON format.

swagger: '2.0'
info:
title: Sample Endpoint
description: >
This is a demo for a sample REST API.
version: 1.0.0
schemes:
- https
host: localhost
basePath: /api
consumes:
- application/json
produces:
- application/json
paths:
/registration:
post:
operationId: registerMember
summary: Member Registration Endpoint.
description: >
This API is used to register memebrs.
tags:
- Member Registration
parameters:
- in: body
name: member_details
description: The details of the new member to be registered.
schema:
$ref: '#/definitions/MemberDetails'
responses:
'200':
description: OK
schema:
$ref: '#/definitions/Success'
'400':
description: Bad Request
schema:
$ref: '#/definitions/Error'
definitions:
Success:
properties:
memberID:
type: string
description: Successful operation.
example: "1234A"
required:
- memberID
Error:
properties:
error:
type: string
description: Invalid input.
example: "invalid_request"
required:
- error
MemberDetails:
type: array
items:
type: object
required:
- memberName
- memberAge
properties:
memberName:
type: string
example: Dewni
memberAge:
type: integer
example: 20

Once you have written the specification download it as a YAML file.

Step 02:

The next step is to create the maven project. Add the downloaded YAML file to resources folder.

There are some POM configurations to be added as follows.

<build>
<plugins>

<plugin>
<groupId>org.wso2.maven.plugins</groupId>
<artifactId>swagger2cxf-maven-plugin</artifactId>
<version>1.0-SNAPSHOT</version>
<configuration>
<inputSpec>${project.basedir}/src/main/resources/member_registration.yaml</inputSpec>
</configuration>
</plugin>

<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<executions>
<execution>
<id>add-source</id>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>src/gen/java</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>

</plugins>
</build>

Make sure to change <inputSpec>${project.basedir}/src/main/resources/member_registration.yaml</inputSpec> according to your requirements (name and location of the YAML file).

Now comes the interesting part. Use “mvn swagger2cxf:generate” command to generate the server stub. Congratulations :) now you have auto generated code for your REST API.

The auto generated code will be inside the src/gen/java folder and inside main/java folder, impl file((s) will be generated.

The programming logic for the REST API according to your requirements should be added to the impl.

For this article I will be keeping the impl as it is.

Step 03:

Now let’s test the sample project with the generated code. For this we need to build a WAR file. To achieve this there are some more POM configurations to be added. The final POM file will look as follow.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>SwaggerCodeGenProject</groupId>
<artifactId>SwaggerCodeGenProject</artifactId>
<version>1.0-SNAPSHOT</version>

<packaging>war</packaging>

<build>
<plugins>

<plugin>
<groupId>org.wso2.maven.plugins</groupId>
<artifactId>swagger2cxf-maven-plugin</artifactId>
<version>1.0-SNAPSHOT</version>
<configuration>
<inputSpec>${project.basedir}/src/main/resources/member_registration.yaml</inputSpec>
</configuration>
</plugin>

<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<executions>
<execution>
<id>add-source</id>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>src/gen/java</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.2</version>
<configuration>
<webResources>
<resource>
<!-- this is relative to the pom.xml directory -->
<directory>src/main/webapp</directory>
</resource>
</webResources>
<warName>memberRegistration</warName>
</configuration>
</plugin>

</plugins>
</build>


<dependencies>

<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxrs</artifactId>
<version>3.1.4</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-rs-service-description</artifactId>
<version>3.1.4</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
<version>1.8.6</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.8.6</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-jaxrs</artifactId>
<version>1.8.6</version>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.1.6.RELEASE</version>
</dependency>

<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-jaxrs</artifactId>
<version>1.5.2</version>
</dependency>
</dependencies>

</project>

You can give the preferred name of the WAR file to be generated inside the <warName> tag of the maven-war-plugin.

There is another very important task to be done. That is to add a web.xml as given below to webapp -> WEB-INF folder (you can find an auto generated beans.xml file there).

<?xml version="1.0" encoding="UTF-8"?>

<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

<display-name>Sample REST API</display-name>
<description>Sample REST API</description>

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/beans.xml</param-value>
</context-param>

<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>

<servlet>
<servlet-name>CXFServlet</servlet-name>
<servlet-class>
org.apache.cxf.transport.servlet.CXFServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>

<session-config>
<session-timeout>60</session-timeout>
</session-config>

</web-app>

Finally let’s build the project using the command “mvn clean install”. The war file will be generated inside the target folder.

Step 04:

Final step is to deploy the webapp (I will be using Tomcat) and test it using the Postman app.

Put the generated WAR file inside the webapps folder of the Apache Tomcat server and start the server.

Add the required headers and the body of the POST request to be sent. Note that in the url https://localhost:9443/memberRegistration/registration “memberRegistration” indicates the name of the WAR file and “registration” is the path name given to the POST method of the swagger specification.

You will obtain the following response if the POST request is successful :)

Finally we have reached the end of this article. I hope you got an understanding on automatic code generation using Swagger Codegen. Now it’s time for you to get out and there and write the actual logic in the impl.

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.