PhoenixNAP Logo

Spring MVC-RAML Plugin Build Status Apache License 2 Maven Central

The Spring MVC-RAML project aims to enforce contract-first approach for projects using Spring MVC framework. The idea is to manually maintain RAML file as a single source of truth and to use this plugin to generate web layer - Spring controllers and domain objects. If the plugin is used as part of a build, application's code will always be in line with RAML documentation.

The plugin is designed to be run on Java 8 code which has been compiled with argument name information.

Sample Project

A sample project that includes a SpringMVC Server implementation using the Decorator pattern as well as a RestTemplate based REST client is available here: SpringMVC RAML Contract First Sample. This sample is based on the contract first scenario whereby the RAML document is authored and used as the basis for implementation

Documentation & Getting Support

Usage and documentation are available in the Javadoc and README.md (this file). Kindly contact the developers via email (available in the pom files) if required or open an Issue in our tracking system.

A tutorial about using RAML to document API contracts and how this plugin fit within the process can be found in this PhoenixNAP blog post.

Building from Source

The SpringMVC-RAML plugin uses a Maven-based build system.

Prerequisites

Git and JDK 8 update 20 or later

Be sure that your JAVA_HOME environment variable points to the jdk1.8.0 folder extracted from the JDK download.

License

The SpringMVC-RAML plugin is released under version 2.0 of the Apache License.

Contributing

Pull requests are welcome; Be a good citizen and create unit tests for any bugs squished or features added

Usage - Generating SpringMVC Server Endpoints from a RAML file

Sample Maven Code

The first step is to download and compile these projects using Maven. Simply run mvn clean install in the parent directory and artifact will be compiled. These can optionally be deployed to your Artifactory or similar repo.

Then simply include the following code in the POM of the project you wish to generate RAML for

<plugin>
  <groupId>com.phoenixnap.oss</groupId>
  <artifactId>springmvc-raml-plugin</artifactId>
  <version>2.x.x</version>
  <configuration>
    <ramlPath>{path.to.raml.file}</ramlPath>
    <schemaLocation>{path.to.schema.directory||schema.absolute.url}</schemaLocation>
    <outputRelativePath>/src/generated</outputRelativePath>
    <addTimestampFolder>false</addTimestampFolder>
    <basePackage>com.gen.wow</basePackage>
    <baseUri>/api</baseUri>
    <generateUnreferencedObjects>true</generateUnreferencedObjects>
    <generationConfig>
        <includeAdditionalProperties>false</includeAdditionalProperties>
        ...
    </generationConfig>
    <seperateMethodsByContentType>false</seperateMethodsByContentType>
    <rule>com.phoenixnap.oss.ramlplugin.raml2code.rules.Spring4ControllerStubRule</rule>
    <ruleConfiguration>         
    </ruleConfiguration>
  </configuration>
  <executions>
    <execution>
      <id>generate-springmvc-endpoints</id>
      <phase>compile</phase>
      <goals>
        <goal>generate-springmvc-endpoints</goal>
      </goals>
    </execution>
  </executions>
</plugin>

ramlPath

(required) The path to the file, relative to the project base directory

outputRelativePath

(optional, default: "") Relative path where the generated Java classes will be saved to. Package structure folders will be created relative to this path.

addTimestampFolder

(optional, default: false) Should an extra folder be generated using a timestamp to seperate generations

basePackage

(required) Base package to be used for the java classes to be generated. Model objects will be added in the .model subpackage

schemaLocation

(optional, default: "") The URI or relative path to the folder/network location containing JSON Schemas

baseUri

(optional, default: "") Base URI for generated Spring controllers. This overrules the baseUri attribute from inside the .raml spec.

generateUnreferencedObjects

(optional, default: false) Determines whether POJOs for unreferenced schemas or data types included in the RAML file should be generated.

generationConfig

(optional) This object contains a map of configuration for the JsonSchema2Pojo generator. The full list of configurable attributes, their description and default values can be found here GenerationConfig

injectHttpHeadersParameter

(optional, default: false) If set to true, we will generate a HttpHeaders parameter for each method to allow using request HTTP headers directly.

injectHttpRequestParameter

(optional, default: false) If set to true, we will generate a HttpServletRequest parameter for each method to allow using request HTTP request directly.

seperateMethodsByContentType

(optional, default: false) Should we generate separate API methods for endpoints which define multiple content types in their 200 response.

useJackson1xCompatibility

(optional, default: false) If set to true, we will generate Jackson 1 annotations inside the model objects.

resourceDepthInClassNames

(optional, default: 1) Levels of resource path that will be included in generated class names. If set to -1 entire uri will be included in class name.

resourceTopLevelInClassNames

(optional, default: 0) Top level of resource path that will be included in generated class names. If set to 0 entire URI will be included in class name.

reverseOrderInClassNames

(optional, default: false) Reverse order of resource path that will be included in generated class names. If set to false URI will be included in class name from left to right.

methodsNamingLogic

(optional, default: OBJECTS) Logic used for Java methods name generation. Possible values: OBJECTS (objects like request parameters and return types will be used) and RESOURCES (resource path will be used).

NOTE: This is different from a previous default. Use RESOURCES to get 0.x behavior.

overrideNamingLogicWith

(optional, default: "") The way to override naming logic for Java methods and arguments. Possible values:

dontGenerateForAnnotation

(optional, default: "") When defined, code generation will be skipped for resources and methods annotated with this Annotation. When annotation is set on resource - all methods in the resource and all sub-resources will be ignored. Value of the annotation is not important.

generatedAnnotation

(optional, default: false) Should javax.annotation.Generated annotation be set on all generated classes. The value of the annotation will be com.phoenixnap.oss.ramlplugin.

ruleConfiguration

(optional) This is a key/value map for configuration of individual rules. Not all rules support configuration.

rule

(optional, default: com.phoenixnap.oss.ramlplugin.raml2code.rules.Spring4ControllerStubRule) The rule class to be used for code generation.

Available Rules

Configuration:
    callableResponse: [OPTIONAL] set to 'true' to support asynchronous callables. Default: 'false'
    deferredResultResponse: [OPTIONAL] set to 'true' to support asynchronous deferred results (DeferredResult). Default: 'false'

NOTE: callableResponse and deferredResultResponse are mutually exclusive

Configuration:
    callableResponse: [OPTIONAL] set to 'true' to support asynchronous callables. Default: 'false'
    deferredResultResponse: [OPTIONAL] set to 'true' to support asynchronous deferred results (DeferredResult). Default: 'false'

NOTE: callableResponse and deferredResultResponse are mutually exclusive

Configuration:
    callableResponse: [OPTIONAL] set to 'true' to support asynchronous callables. Default: 'false'
    deferredResultResponse: [OPTIONAL] set to 'true' to support asynchronous deferred results (DeferredResult). Default: 'false'
    simpleReturnTypes: [OPTIONAL] set to 'true' to generate controllers method's return types without ResponseEntity<> wrapper. Will also generate Object instead of ResponseEntity<?> return type for methods when return type is not specified for the endpoint. Default: 'false'
    useShortcutMethodMappings: [OPTIONAL] set to 'true' to generate new shortcut method annotations(e.g. @PutMapping, @GetMapping) instead of old-style @RequestMapping. Default: 'false'

NOTE: callableResponse, deferredResultResponse and simpleReturnTypes are mutually exclusive

Configuration:
    baseUrlConfigurationPath: The path that will be used to load the property for the server url. Default: ${client.url}
    restTemplateFieldName: The name of the RestTemplate field
    restTemplateQualifierBeanName: [OPTIONAL] The name of the bean for the rest template used in the generated client. Default: NONE