Goal of this project is to provide tooling for Maven projects (and maybe Gradle) to generate code from swagger-definitions (yaml or json) during build. This is not a onetime-generator. Code will be generated at every build to make sure your implementation matches your api.
It also provides different templates for code-generation.
Installation
Installation with maven is easy. Just add the following snippet into your pom.xml:
<plugin>
<groupId>org.zalando.maven.plugins</groupId>
<artifactId>swagger-codegen-maven-plugin</artifactId>
<version>${plugin.version}</version>
<configuration>
<apiFile>${project.basedir}/src/main/resources/api.yaml</apiFile>
<language>springinterfaces</language>
<apiPackage>com.yourcompany.api</apiPackage>
<modelPackage>com.yourcompany.model</modelPackage>
</configuration>
<!-- put template-dependency here, directly into plugin -->
<dependencies>
<dependency>
<groupId>org.zalando.stups</groupId>
<artifactId>swagger-codegen-template-spring-interfaces</artifactId>
<version>${template.version}</version>
</dependency>
</dependencies>
</plugin>
Templates
templatename |
---|
|
|
|
|
|
The following examples are generated from the official pet-store-example by swagger.
springinterfaces
When using springinterfaces
as template then the generated code looks like this:
package de.zalando.swagger.api;
import de.zalando.swagger.model.*;
import io.swagger.annotations.*;
import java.util.Map;
import de.zalando.swagger.model.Order;
import java.util.List;
import java.io.InputStream;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestBody;
//
// GENERATED CLASS, DO NOT EDIT
//
@Api(value = "/store")
public interface StoreApi {
@RequestMapping(value="/store/inventory",method=RequestMethod.GET , produces={ "application/json", "application/xml" })
@ApiOperation(value = "Returns pet inventories by status", notes = "Returns a map of status codes to quantities", response = Map.class, responseContainer = "map")
@ApiResponses(value = {
@ApiResponse(code = 200, message = "successful operation")
})
Integer getInventory();
@RequestMapping(value="/store/order",method=RequestMethod.POST , produces={ "application/json", "application/xml" })
@ApiOperation(value = "Place an order for a pet", notes = "", response = Order.class)
@ApiResponses(value = {
@ApiResponse(code = 200, message = "successful operation"),
@ApiResponse(code = 400, message = "Invalid Order")
})
Order placeOrder(@ApiParam(value = "order placed for purchasing the pet" ) @RequestBody Order body);
@RequestMapping(value="/store/order/{orderId}",method=RequestMethod.GET , produces={ "application/json", "application/xml" })
@ApiOperation(value = "Find purchase order by ID", notes = "For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions", response = Order.class)
@ApiResponses(value = {
@ApiResponse(code = 404, message = "Order not found"),
@ApiResponse(code = 200, message = "successful operation"),
@ApiResponse(code = 400, message = "Invalid ID supplied")
})
Order getOrderById(@ApiParam(value = "ID of pet that needs to be fetched",required=true ) @PathVariable("orderId") String orderId);
@RequestMapping(value="/store/order/{orderId}",method=RequestMethod.DELETE , produces={ "application/json", "application/xml" })
@ApiOperation(value = "Delete purchase order by ID", notes = "For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors")
@ApiResponses(value = {
@ApiResponse(code = 404, message = "Order not found"),
@ApiResponse(code = 400, message = "Invalid ID supplied")
})
void deleteOrder(@ApiParam(value = "ID of the order that needs to be deleted",required=true ) @PathVariable("orderId") String orderId);
}
springinterfacesNoSwaggerAnnotations
You can guess by the templates name what the code will look like, right?
package de.zalando.swagger.api;
import de.zalando.swagger.model.*;
import java.util.Map;
import de.zalando.swagger.model.Order;
import java.util.List;
import java.io.InputStream;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestBody;
//
// GENERATED CLASS, DO NOT EDIT
//
public interface StoreApi {
@RequestMapping(value="/store/inventory",method=RequestMethod.GET , produces={ "application/json", "application/xml" })
Integer getInventory();
@RequestMapping(value="/store/order",method=RequestMethod.POST , produces={ "application/json", "application/xml" })
Order placeOrder( @RequestBody Order body);
@RequestMapping(value="/store/order/{orderId}",method=RequestMethod.GET , produces={ "application/json", "application/xml" })
Order getOrderById( @PathVariable("orderId") String orderId);
@RequestMapping(value="/store/order/{orderId}",method=RequestMethod.DELETE , produces={ "application/json", "application/xml" })
void deleteOrder( @PathVariable("orderId") String orderId);
}
springinterfacesResponseEntity
If you like to use Springs ResponseEntity as return-value.
package de.zalando.swagger.api;
import de.zalando.swagger.model.*;
import io.swagger.annotations.*;
import java.util.Map;
import de.zalando.swagger.model.Order;
import java.util.List;
import java.io.InputStream;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestBody;
//
// GENERATED CLASS, DO NOT EDIT
//
@Api(value = "/store")
public interface StoreApi {
@RequestMapping(value="/store/inventory",method=RequestMethod.GET , produces={ "application/json", "application/xml" })
@ApiOperation(value = "Returns pet inventories by status", notes = "Returns a map of status codes to quantities", response = Map.class, responseContainer = "map")
@ApiResponses(value = {
@ApiResponse(code = 200, message = "successful operation")
})
ResponseEntity<Integer> getInventory();
@RequestMapping(value="/store/order",method=RequestMethod.POST , produces={ "application/json", "application/xml" })
@ApiOperation(value = "Place an order for a pet", notes = "", response = Order.class)
@ApiResponses(value = {
@ApiResponse(code = 200, message = "successful operation"),
@ApiResponse(code = 400, message = "Invalid Order")
})
ResponseEntity<Order> placeOrder(@ApiParam(value = "order placed for purchasing the pet" ) @RequestBody Order body);
@RequestMapping(value="/store/order/{orderId}",method=RequestMethod.GET , produces={ "application/json", "application/xml" })
@ApiOperation(value = "Find purchase order by ID", notes = "For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions", response = Order.class)
@ApiResponses(value = {
@ApiResponse(code = 404, message = "Order not found"),
@ApiResponse(code = 200, message = "successful operation"),
@ApiResponse(code = 400, message = "Invalid ID supplied")
})
ResponseEntity<Order> getOrderById(@ApiParam(value = "ID of pet that needs to be fetched",required=true ) @PathVariable("orderId") String orderId);
@RequestMapping(value="/store/order/{orderId}",method=RequestMethod.DELETE , produces={ "application/json", "application/xml" })
@ApiOperation(value = "Delete purchase order by ID", notes = "For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors")
@ApiResponses(value = {
@ApiResponse(code = 404, message = "Order not found"),
@ApiResponse(code = 400, message = "Invalid ID supplied")
})
void deleteOrder(@ApiParam(value = "ID of the order that needs to be deleted",required=true ) @PathVariable("orderId") String orderId);
}
springinterfacesResponseEntityNoSwaggerAnnotations
You can guess again …
package de.zalando.swagger.api;
import de.zalando.swagger.model.*;
import java.util.Map;
import de.zalando.swagger.model.Order;
import java.util.List;
import java.io.InputStream;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestBody;
//
// GENERATED CLASS, DO NOT EDIT
//
public interface StoreApi {
@RequestMapping(value="/store/inventory",method=RequestMethod.GET , produces={ "application/json", "application/xml" })
ResponseEntity<Integer> getInventory();
@RequestMapping(value="/store/order",method=RequestMethod.POST , produces={ "application/json", "application/xml" })
ResponseEntity<Order> placeOrder( @RequestBody Order body);
@RequestMapping(value="/store/order/{orderId}",method=RequestMethod.GET , produces={ "application/json", "application/xml" })
ResponseEntity<Order> getOrderById( @PathVariable("orderId") String orderId);
@RequestMapping(value="/store/order/{orderId}",method=RequestMethod.DELETE , produces={ "application/json", "application/xml" })
void deleteOrder( @PathVariable("orderId") String orderId);
}
jaxrsinterfaces
There exist also an template for JAX-RS.
package de.zalando.swagger.api;
import de.zalando.swagger.model.*;
import io.swagger.annotations.*;
import java.util.Map;
import de.zalando.swagger.model.Order;
import java.util.List;
import de.zalando.swagger.api.NotFoundException;
import java.io.InputStream;
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
import org.glassfish.jersey.media.multipart.FormDataParam;
import javax.ws.rs.core.Response;
import javax.ws.rs.*;
@Path("/store")
@Api(value = "/store", description = "the store API")
public interface StoreApi {
@GET
@Path("/inventory")
@Produces({ "application/json", "application/xml" })
// Integer
@ApiOperation(value = "Returns pet inventories by status", notes = "Returns a map of status codes to quantities", response = Integer.class, responseContainer = "map")
@ApiResponses(value = {
@ApiResponse(code = 200, message = "successful operation") })
public Response getInventory()
throws NotFoundException;
@POST
@Path("/order")
@Produces({ "application/json", "application/xml" })
// Order
@ApiOperation(value = "Place an order for a pet", notes = "", response = Order.class)
@ApiResponses(value = {
@ApiResponse(code = 200, message = "successful operation"),
@ApiResponse(code = 400, message = "Invalid Order") })
public Response placeOrder(@ApiParam(value = "order placed for purchasing the pet" ) Order body)
throws NotFoundException;
@GET
@Path("/order/{orderId}")
@Produces({ "application/json", "application/xml" })
// Order
@ApiOperation(value = "Find purchase order by ID", notes = "For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions", response = Order.class)
@ApiResponses(value = {
@ApiResponse(code = 404, message = "Order not found"),
@ApiResponse(code = 200, message = "successful operation"),
@ApiResponse(code = 400, message = "Invalid ID supplied") })
public Response getOrderById(@ApiParam(value = "ID of pet that needs to be fetched",required=true ) @PathParam("orderId") String orderId)
throws NotFoundException;
@DELETE
@Path("/order/{orderId}")
@Produces({ "application/json", "application/xml" })
// Void
@ApiOperation(value = "Delete purchase order by ID", notes = "For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors", response = Void.class)
@ApiResponses(value = {
@ApiResponse(code = 404, message = "Order not found"),
@ApiResponse(code = 400, message = "Invalid ID supplied") })
public Response deleteOrder(@ApiParam(value = "ID of the order that needs to be deleted",required=true ) @PathParam("orderId") String orderId)
throws NotFoundException;
}
Further Configuration Options
There are some more configuration-options for the maven-plugin.
<plugin>
... skipped ...
<configuration>
<apiFile>${project.basedir}/src/main/resources/api.yaml</apiFile>
<language>springinterfaces</language>
<apiPackage>com.yourcompany.api</apiPackage>
<modelPackage>com.yourcompany.model</modelPackage>
<!-- skip generation for api -->
<skipApigeneration>true</skipApigeneration>
<!-- model-definitions to exclude from generation -->
<excludedModels>
<excludedModel>Application</excludedModel>
<excludedModel>ApplicationDetails</excludedModel>
</excludedModels>
<!-- skip generation of model-definitions completely -->
<skipModelgeneration>true</skipModelgeneration>
<yamlToJson>true</yamlToJson>
<yamlToJsonOutputDirectory>${project.build.directory}/classes</yamlToJsonOutputDirectory>
<enableBuilderSupport>true</enableBuilderSupport>
<enable303>true</enable303>
</configuration>
<!-- put template-dependency here, directly into plugin -->
... skipped ...
</plugin>
option | description |
---|---|
|
transform the yaml into json |
|
location for generated json-file |
|
creates simple builder for model-definitions |
|
add JSR-303 annotations if possible to model-definitions |
|
Models to exclude from generation |
|
completely skips generation of model-definitions |
|
maybe you only want to generate the model, because api is shared by another module |