Spike: MODKBEKBJ-46 - Spring initiative investigation
Goal:
The main goal of the spike was investigation if the proposed plugin meets project initial requirements.
Initial requirements:
- for endpoints it has to generate interfaces or classes that could be extended to implement the necessary logic [MUST];
support !include directive in RAML files like below:
types: note: !include note.json noteCollection: !include noteCollection.json errors: !include raml-util/schemas/errors.schema
- support definition of a single element in collection as $ref
Investigation results:
Initial requirement:
for endpoints it has to generate interfaces or classes that could be extended to implement the necessary logic [MUST];
Result:
The plugin provides several rules an ability to generate interfaces. To achiev this you have to specify the rule name in pom.xml file
<configuration> <rule>com.phoenixnap.oss.ramlplugin.raml2code.rules.Spring4ControllerInterfaceRule</rule> </configuration>
Here is the raml file which were used to test:
this are the Controllers generated by plugin:
and Models
- Rules description can be found here https://github.com/phoenixnap/springmvc-raml-plugin#rule
- Sample module can be found here. The pom file which uses this rule can be found here
Initial requirement:
2. support !include directive in RAML files like below :
types: note: !include note.json noteCollection: !include noteCollection.json errors: !include raml-util/schemas/errors.schema3. support definition of a single element in collection as $ref
Result:
Plugin is able to read !include
directive with json
and schema
extension but the result of the parsing does not feet our expectations.
For instance we declared type in following raml
file
with next content inside
The module will create Controller for this raml
file with one "but"
As we can see the the particular type of the response was not defined and because of it models for "Drink" and "DrinkCollection" also were not created. The only model was created is general request, which fields do not satisfy our requirement.
Despite of the fact that currently correct type selection is not provided we can probably inject custom logic in the phase of distinguishing the type in ApiActionMetadata.parseResponse().
package com.phoenixnap.oss.ramlplugin.raml2code.data; ... private void parseResponse(JCodeModel codeModel, String responseContentTypeFilter) { RamlResponse response = RamlHelper.getSuccessfulResponse(action); if (response != null && response.getBody() != null && !response.getBody().isEmpty()) { for (Entry<String, RamlMimeType> body : response.getBody().entrySet()) { if (responseContentTypeFilter == null || body.getKey().equals(responseContentTypeFilter)) { if (body.getKey().toLowerCase().contains("json") || body.getKey().toLowerCase().equals("body")) { // if we have a json type we need to return an object // Continue here! ApiBodyMetadata responseBody = null; RamlDataType type = body.getValue().getType(); String schema = body.getValue().getSchema(); // prefer type if we have it. String name = StringUtils.capitalize(getName()) + "Response"; if (type != null && type.getType() != null && !(type.getType() instanceof JSONTypeDeclaration)) { responseBody = RamlTypeHelper.mapTypeToPojo(codeModel, parent.getDocument(), type.getType()); } else if (StringUtils.hasText(schema)) { responseBody = SchemaHelper.mapSchemaToPojo(parent.getDocument(), schema, Config.getPojoPackage(), name, null); } if (responseBody != null) { this.responseBody.put(body.getKey(), responseBody); } } } } } }
the following declaration
types: drinkCollection: !include drinkCollection.json
is already resolved as JSONTypeDeclaration
, so the logic inside SchemaHelper.mapSchemaToPojo(...)
can be modified to satisfy our needs.