Skip to content
This repository has been archived by the owner on Jan 21, 2024. It is now read-only.

Add raml-to-jaxrs article example proj and base #6

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 90 additions & 0 deletions raml-for-jaxrs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
---
publication: 'RAML Playground'
tags: ['Api Design', 'RAML', 'query params']
license: 'cc-40-by'
---


**NOT FOR PUBLISHING**


## General

The example project located in `example-proj` describes following features of `raml-to-jaxrs` (taken from https://github.com/mulesoft-labs/raml-for-jax-rs/blob/master/raml-to-jaxrs/README.md):

* Generates interfaces from JSON Schema and RAML Types;
* A response object wrapper is created for each resource action in order to guide the implementer in producing only results that are compatible with the RAML definition;
* Custom annotations are generated for HTTP methods that are not part of the core JAX-RS specification;
* Objects defined as RAML 1.0 objects are generated;
* Objects are also generated based on JSON schemas to represent request/response entities;
* This example uses Maven;


## Example project structure

*README.md*: Readme from original example project repo. May be useful to pull some info from it. Can be deleted.

*pom.xml*: Required. I guess it's a java project setup file. Some info regarding its parts can be found in *README.md*.

*src/main/java/server/ricks/RicksImpl.java*: Simple server to run generated JAX-RS project. Code can be demonstrated without it, but it's needed to demonstrate the project working. I guess users could create their own server but for demo purposes I think it may be good to include this one. Maybe its code should be listed after some title like "now let's create a simple server to test generated jax-rs server".

*src/main/java/server/ricks/RicksImpl.java*: Required for server to run. Implements interfaces generated by the tool. This is logic for handling HTTP requests to the server.

*src/main/resources/api.raml*: Required. API definition.

*src/main/resources/includes/rick.json*: Required. JSON Scheme used in the API definition.

*src/main/resources/includes/ricks-library.raml*: Required. RAML Library that defines type used in API definition.

**Generated files (appear after generating jax-rs project):**

*target/generated-sources/raml-to-jaxrs-maven-plugin/example/jsonschema/ResponseDelegate.java*: Looks like a delegate for Response. Is inherited in generated interfaces.

*target/generated-sources/raml-to-jaxrs-maven-plugin/example/jsonschema/Rick.java*: Model generated from RAML Type. Defines setters/getters/etc.

*target/generated-sources/raml-to-jaxrs-maven-plugin/example/jsonschema/Ricks.java*: API interface declaring all the HTTP methods, response classes.


## To run the example:

1. Install Maven
2. In terminal run:

```sh
cd example-proj
mvn install
mvn raml:generate
mvn exec:java
```

3. Now you have a server running at `localhost:9998`


## Demo of the API/server

http GET http://localhost:9998/ricks
http POST http://localhost:9998/ricks slug=c137 name='Rick Sanchez' age:=70 inCouncil:=false
http POST http://localhost:9998/ricks slug=riq name='Riq IV' age:=70 inCouncil:=true
http POST http://localhost:9998/ricks slug=zar name='Zeta Alpha Rick' age:=70 inCouncil:=true
http POST http://localhost:9998/ricks slug=prime name='Rick Prime' age:=60 inCouncil:=true
http GET http://localhost:9998/ricks
http GET http://localhost:9998/ricks/c137
http GET http://localhost:9998/ricks/riq
http GET http://localhost:9998/ricks/zar
http GET http://localhost:9998/ricks/prime

Same data in JSON if needed:

{"slug": "c137", "name": "Rick Sanchez", "age": 70, "inCouncil": false}
{"slug": "riq", "name": "Riq IV", "age": 70, "inCouncil": true}
{"slug": "prime", "name": "Rick Prime", "age": 60, "inCouncil": true}
{"slug": "zar", "name": "Zeta Alpha Rick", "age": 70, "inCouncil": true}


## Things to note

* Request validation does not work. I guess it's not supposed to work and code for it should not be generated by the tool;
* Requesting unexisting urls does not return 404. I guess that's also supposed to be immplemented by the tool users;
* As we discussed, `mvn install` step may be already run by Java IDEs;
* Licences to `StartServer.java` and `RicksImpl.java` are added when running `mvn install` so they can be removed for article purposes;
* Objects are stored in HashMap instead of real db;
36 changes: 36 additions & 0 deletions raml-for-jaxrs/example-proj/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
## Simple example
JSONSchema types are generated by [jsonschema2pojo](https://github.com/joelittlejohn/jsonschema2pojo)

```xml
<configuration>
<ramlFile>${project.build.resources[0].directory}/api.raml</ramlFile>
<resourcePackage>example.jsonschema</resourcePackage>
<jsonMapper>jackson2</jsonMapper>
<jsonMapperConfiguration>
<includeHashcodeAndEquals>true</includeHashcodeAndEquals>
</jsonMapperConfiguration>
</configuration>
```
The `jsonMapper` configuration parameter specifies which annotation strategy
should be used by jsonschema2pojo. Available options are `jackson`, `jackson2` and `gson`

The `jsonMapperConfiguration` parameter allows for some configuration of the mapper.
These are the currently supported values for this configuration.

* `IncludeJsr303Annotations`
* `UseCommonsLang3`
* `GenerateBuilders`
* `IncludeHashcodeAndEquals`
* `CustomAnnotator`
* `IncludeToString`
* `UseLongIntegers`
* `IncludeConstructors`
* `ConstructorsRequiredPropertiesOnly`
* `IncludeAccessors`
* `UseJodaDates`
* `UseJodaLocalDates`
* `UseJodaLocalTimes`
* `DateTimeType`
* `DateType`

You can find more information on this jsonschema2pojo documentation [page](http://joelittlejohn.github.io/jsonschema2pojo/site/0.4.14/generate-mojo.html).
72 changes: 72 additions & 0 deletions raml-for-jaxrs/example-proj/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<?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>

<parent>
<groupId>org.raml.jaxrs</groupId>
<artifactId>maven-examples</artifactId>
<version>3.0.1-SNAPSHOT</version>
</parent>

<artifactId>ricks-example</artifactId>
<properties>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>

<dependencies>
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>javax.ws.rs-api</artifactId>
</dependency>
<dependency>
<groupId>org.raml.jaxrs</groupId>
<artifactId>jaxrs-code-generator</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-jetty-http</artifactId>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.raml.jaxrs</groupId>
<artifactId>raml-to-jaxrs-maven-plugin</artifactId>
<configuration>
<ramlFile>${project.build.resources[0].directory}/api.raml</ramlFile>
<resourcePackage>example.jsonschema</resourcePackage>
<jsonMapper>jackson2</jsonMapper>
<jsonMapperConfiguration>
<includeHashcodeAndEquals>true</includeHashcodeAndEquals>
</jsonMapperConfiguration>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<configuration>
<mainClass>server.ricks.StartServer</mainClass>
</configuration>
<executions>
<execution>
<goals>
<goal>java</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package server.ricks;

import example.jsonschema.Rick;
import example.jsonschema.Ricks;

import java.util.ArrayList;
import java.util.List;
import java.util.HashMap;

public class RicksImpl implements Ricks {

public static HashMap<String, Rick> ricksMap = new HashMap<String, Rick>();

@Override
public GetRicksResponse getRicks() {
List<Rick> ricks = new ArrayList<Rick>(this.ricksMap.values());
return GetRicksResponse.respond200WithApplicationJson(ricks);
}

@Override
public PostRicksResponse postRicks(Rick entity) {
this.ricksMap.put(entity.getSlug(), entity);
return PostRicksResponse.respond200WithApplicationJson(entity);
}

@Override
public GetRicksBySlugResponse getRicksBySlug(String slug) {
return GetRicksBySlugResponse.respond200WithApplicationJson(
this.ricksMap.get(slug));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package server.ricks;

import org.eclipse.jetty.server.Server;
import org.glassfish.jersey.jetty.JettyHttpContainerFactory;
import org.glassfish.jersey.server.ResourceConfig;

import javax.ws.rs.core.UriBuilder;
import java.net.URI;

public class StartServer {

public static void main(String[] args) throws Exception {
URI baseUri = UriBuilder.fromUri("http://localhost/").port(9998).build();
ResourceConfig config = new ResourceConfig(RicksImpl.class);
Server server = JettyHttpContainerFactory.createServer(baseUri, config);
server.start();
}
}
39 changes: 39 additions & 0 deletions raml-for-jaxrs/example-proj/src/main/resources/api.raml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#%RAML 1.0
title: Ricks API
version: v1
baseUri: https://api.github.com
mediaType: application/json

types:
Rick: !include includes/rick.json

uses:
RicksLib: includes/ricks-library.raml

/ricks:
description: Crucial information about Ricks
get:
responses:
200:
body:
application/json:
type: RicksLib.Rick[]
post:
body:
application/json:
type: RicksLib.Rick
responses:
200:
body:
application/json:
type: RicksLib.Rick

/{slug}:
uriParameters:
slug: string
get:
responses:
200:
body:
application/json:
type: Rick
Copy link
Contributor

@jstoiko jstoiko Jun 6, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not re-sure RicksLib.Rick here? I understand it has something to do with jsonschema2pojo but what would happen if it was a RAML type instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's just a way to showcase that JSON Schema and RAML Data Type can be used alongside. RicksLib.Rick can be used in all places.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please let me know if I should remove JSON Schema and use RicksLib.Rick instead.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would it generate similar java code?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like generated files (inside raml-playground/raml-for-jaxrs/example-proj/target/generated-sources/raml-to-jaxrs-maven-plugin/example/jsonschema/) are identical.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In that case, let's use only the type Lib.Rick

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ugh, I was wrong. On previous test everything work fine, but then I removed generated code folder completely and tried to install the project. And now looks like class Rick (inside /raml-playground/raml-for-jaxrs/example-proj/target/generated-sources/raml-to-jaxrs-maven-plugin/example/jsonschema/Rick.java) implementation is not generated when JSON Schema is not used 😕

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both classes had the same name (json and raml). In the pull request I submitted to @postatum, I changed the name from Rick to JsonRick. That said, I'm not convinced in a small example that we should be using JsonSchema: jsonschema is a bit of an outlier in RAML (arrays and such are not handled the same way...). And the project itself has examples of this.

I've also made the project standalone: no parent in the pom.xml, everything explicitly stated.

25 changes: 25 additions & 0 deletions raml-for-jaxrs/example-proj/src/main/resources/includes/rick.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"type": "object",
"$schema": "http://json-schema.org/draft-03/schema",
"id": "http://jsonschema.net",
"required": true,
"properties": {
"slug": {
"type": "string",
"required": true
},
"name": {
"type": "string",
"required": true,
"minLength": 3
},
"age": {
"type": "integer",
"required": true
},
"inCouncil": {
"type": "boolean",
"required": true
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#%RAML 1.0 Library

types:
Rick:
type: object
properties:
slug: string
name:
type: string
minLength: 3
age: integer
inCouncil: boolean