Response Examples
The model select box in the responses can be expanded to show examples:
Examples are provided for any supported Accept type based on the serializers defined on your
servlet/method.
Examples are pulled from the examples attribute in the response object of the generated Swagger JSON:
"/pet/{petId}": {
"get": {
"operationId": "getPet",
"summary": "Find pet by ID",
"description": "Returns a single pet",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/Pet"
},
"examples": {
"text/html+stripped": "<table>\n\t<tr>\n\t\t<td>id</td>\n\t\t<td>\t\t\t<a href=\"...",
"text/html+schema": "<html>\n\t<head>\n\t\t<link rel='icon' href='$U{servlet:/htdocs/cat.png}'/>...",
"application/json": "{\n\t\"id\": 123,\n\t\"species\": {\n\t\t\"name\": \"Dog\",\n\t\t\"id\": 123\n\t},\n\t\"name\...",
"application/json+simple": "{\n\tid: 123,\n\tspecies: {\n\t\tname: 'Dog',\n\t\tid: 123\n\t},\n\tname: 'Doggie',\n\...",
"application/json+schema": "{\n\t\"type\": \"object\",\n\t\"properties\": {\n\t\t\"id\": {\n\t\t\t\"type\": \"inte...",
"text/xml": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Pet>\n\t<id>123</id>\n\t<spec...",
"text/xml+schema": "<schema xmlns=\"http://www.w3.org/2001/XMLSchema\" targetNamespace=\"http://www.apache.org/...",
"text/uon": "(\n\tid=123,\n\tspecies=(\n\t\tname=Dog,\n\t\tid=123\n\t),\n\tname=Doggie,\n\ttags=@(\n\t\t(\n\t\t\tn...",
"application/x-www-form-urlencoded": "id=123\n&species=(\n\tname=Dog,\n\tid=123\n)\n&name=Doggie\n&tags=@(\n\t(\n\...",
"text/openapi": "(\n\tid=123,\n\tspecies=(\n\t\tname=Dog,\n\t\tid=123\n\t),\n\tname=Doggie,\n\ttags=@(\n\t\t(\n\t\...",
"octal/msgpack": "86 A2 69 64 7B A7 73 70 65 63 69 65 73 82 A4 6E 61 6D 65 A3 44 6F 67 A2 69 64 7B A4 6E 61 6D 65 ...",
"text/xml+soap": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Envelope soap=\"http://www.w3.org/2003/05/...",
"text/plain": "{id:123,species:{name:'Dog',id:123},name:'Doggie',tags:[{name:'MyTag',id:123}],price:0.0,status:'AV...",
"text/xml+rdf": "<rdf:RDF\n xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"\n xmlns:j=\"http://...",
"text/xml+rdf+abbrev": "<rdf:RDF\n xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"\n xmlns:j=\"...",
"text/turtle": "@prefix jp: <http://www.apache.org/juneaubp/> .\n@prefix j: <http://www.apache...",
"text/n-triple": "_:A720f0f4fX3aX165d4974933X3aXX2dX7f93 <http://www.apache.org/juneaubp/name> \"Dog\" .\n_:...",
"text/n3": "@prefix jp: <http://www.apache.org/juneaubp/> .\n@prefix j: <http://www.apache.org..."
There are several options for defining examples for response bodies:
-
{@link oaj.http.annotation.Response#example() @Response(example)} annotation.
-
{@link oaj.http.annotation.Response#examples() @Response(examples)} annotation.
-
Defining an "examples" field in the inherited Swagger JSON response object (classpath file or @ResourceSwagger(value)/@MethodSwagger(value)).
-
Defining an "examples" field in the Swagger Schema Object for the response object (including referenced "$ref" schemas).
-
Allowing Juneau to auto-generate a code example.
The {@link oaj.http.annotation.Response#example @Response(example)} annotation can be used on either your @RestMethod-annotated
method or return class to define the example of the body.
// A JSON representation of a Pet object.
@Response(
example="{name:'Doggie',price:9.99,species:'Dog',tags:['friendly','cute']}"
)
This is a Simple JSON representation of the body that is converted to a POJO and then serialized to all the registered serializers on the REST method to produce examples for all
supported language types.
These values are then used to automatically populate the examples field.
Direct per-media-type examples can also be defined using the {@link oaj.http.annotation.Response#examples @Response(examples)} annotation:
// A JSON representation of a PetCreate object.
@Response(
examples={
"'application/json':'{name:\\'Doggie\\',species:\\'Dog\\'}',",
"'text/uon':'(name:Doggie,species=Dog)'"
}
)
Juneau also supports auto-generation of JSON-Schema directly from POJO classes.
By default, the generated swagger uses to the {@link oaj.jsonschema.JsonSchemaGenerator#JSONSCHEMA_addExamplesTo JSONSCHEMA_addExamplesTo}
setting to automatically add examples to beans, collections, arrays, and maps:
In particular, examples can be defined via static methods, fields, and annotations on the classes themselves.
// Annotation on class.
@Example("{name:'Doggie',price:9.99,species:'Dog',tags:['friendly','cute']}")
public class PetCreate {
...
}
// Annotation on static method.
public class PetCreate {
@Example
public static PetCreate sample() {
return new PetCreate("Doggie", 9.99f, "Dog", new String[] {"friendly","cute"});
}
}
// Static method with specific name 'example'.
public class PetCreate {
public static PetCreate example() {
return new PetCreate("Doggie", 9.99f, "Dog", new String[] {"friendly","cute"});
}
}
// Static field.
public class PetCreate {
@Example
public static PetCreate EXAMPLE = new PetCreate("Doggie", 9.99f, "Dog", new String[] {"friendly","cute"});
}
Examples can also be specified via generic properties as well using the {@link oaj.BeanContext#BEAN_examples} property
or {@link oaj.annotation.BeanConfig#examples @BeanConfig(examples)} annotation at either the class or method level.
// Examples defined at class level.
@Rest(...)
@BeanConfig(
examples="{PetCreate: {name:'Doggie',price:9.99,species:'Dog',tags:['friendly','cute']}}"
)
Response headers are also rendered in the Swagger UI:
These can be auto-generated from {@link oaj.http.annotation.ResponseHeader @ResponseHeader} annotations defined on either
method parameters or type classes.
The example above shows one of each:
@RestMethod(
name=GET,
path="/user/login",
summary="Logs user into the system",
swagger=@MethodSwagger(
tags="user"
)
)
public Ok login(
@Query(
name="username",
description="The username for login",
required=true,
example="myuser"
)
String username,
@Query(
name="password",
description="The password for login in clear text",
required=true,
example="abc123"
)
String password,
@ResponseHeader(
name="X-Rate-Limit",
type="integer",
format="int32",
description="Calls per hour allowed by the user.",
example="123"
)
Value<Integer> rateLimit,
Value<ExpiresAfter> expiresAfter,
RestRequest req,
RestResponse res
) throws InvalidLogin, NotAcceptable {
if (! store.isValid(username, password))
throw new InvalidLogin();
Date d = new Date(System.currentTimeMillis() + 30 * 60 * 1000);
req.getSession().setAttribute("login-expires", d);
rateLimit.set(1000);
expiresAfter.set(new ExpiresAfter(d));
return OK;
}
@ResponseHeader(
name="X-Expires-After",
type="string",
format="date-time",
description="Date in UTC when token expires",
example="2012-10-21"
)
public static class ExpiresAfter {
private final Calendar c;
public ExpiresAfter(Date d) {
this.c = new GregorianCalendar();
c.setTime(d);
}
public Calendar toCalendar() {
return c;
}
}