Custom Annotations
One Network builds on the JAX-RS specification annotations by providing a set of additional custom annotations for documenting RESTful web services.
Table 6.2. Custom Annotations
Annotation |
||
ModulePublic |
SOURCE |
METHOD |
RestParam |
SOURCE |
PARAMETER |
RestObjectProperty |
SOURCE |
METHOD |
RestRequest |
SOURCE |
METHOD |
RestResponse |
SOURCE |
METHOD |
RestEnumeration |
SOURCE |
PACKAGE |
RestException |
RUNTIME |
TYPE |
RestFooter |
SOURCE |
PACKAGE |
We will explore each custom annotation in detail in the sections below.
ModulePublic
ModulePublic is a marker annotation. To make your API public, annotate your webservice with@ModulePublic.
Usage:
@ModulePublic
@GET
public
JSONObject getBook(
@QueryParam
(
"SysId"
) Long sysId) {
}
Documentation is generated only for Public APIs. Any webservice which is not annotated with @ModulePublic is treated as a private API and will not be documented.
RestParam
RestParam is an annotation that works in conjunction with the @QueryParam or @PathParam or @FormParam annotations of the JAX-RS specification. This annotation provides attributes, shown below, to include additional details about the parameters for documenting.
description: Provides a description of the parameter.
required: Boolean value representing if this parameter is required or optional. (This is not enforced at runtime, it is purely documentational.)
sampleValue: A sample value of the parameter.
Usage:
@ModulePublic
@GET
public
JSONObject getBook(
@QueryParam
(
"SysId"
)
@RestParam
(description=
"Unique identifier for a book"
, required=
true
, sampleValue=
"10000"
) Long sysId) {
}
@ModulePublic
@GET
@Path
(
"{SysId}"
)
public
JSONObject getBook(
@PathParam
(
"SysId"
)
@RestParam
(description=
"Unique identifier for a book"
, required=
true
, sampleValue=
"10000"
) Long sysId) {
}
@ModulePublic
@POST
public
JSONObject getBook(
@FormParam
(
"SysId"
)
@RestParam
(description=
"Unique identifier for a book"
, required=
true
, sampleValue=
"10000"
) Long sysId) {
}
@RestParam cannot be used alone. It has to be used in conjunction with @QueryParam or @PathParam or @FormParam annotations.
RestObjectProperty
RestObjectProperty is used to document a property within a JSON sent in a request body or returned in a response body. It has the following attributes:
name: Name of the property.
description: Provides a description about the parameter.
required: Boolean value. When used with @RestRequest, it specifies whether this property is required or optional in the request body. When used with @RestResponse, it specifies wheth er this property is always included or not in the response body. (This is not enforced at runtime, it is purely documentational.)
sampleValue: A sample value of the parameter.
Usage:
@ModulePublic
@GET
@Path
(
"{SysId}"
)
@RestResponse
(description=
"Returns a book"
,
properties= {
@RestObjectProperty
(name=
"SysId"
, description=
"Unique identifier for a book"
, required=
true
, sampleValue=
"10000"
),
@RestObjectProperty
(name=
"Title"
, description=
"Title of the book"
, required=
true
, sampleValue=
"Learning Platform"
)}
)
public
JSONObject getBook(
@PathParam
(
"SysId"
)
@RestParam
(description=
"Unique identifier for a book"
, required=
true
, sampleValue=
"10000"
) Long sysId) {
}
@ModulePublic
@POST
@RestRequest
(description=
"Create a book"
,
properties= {
@RestObjectProperty
(name=
"Title"
, description=
"Title of the book"
, required=
true
, sampleValue=
"Learning Platform"
)}
)
public
JSONObject createBook(JSONObject book) {
}
@RestObjectProperty cannot be used alone. It has to be used in inside @RestRequest or @RestResponse annotations.
RestRequest
RestRequest is used to document request body. A collection of @RestObjectProperty annotations can be used inside a @RestRequest. It has the following attributes:
description: Provides a description about the parameter.
sampleValue: A sample value of the parameter.
RestObjectProperty[]: A collection of RestObjectProperty annotations to document request body properties.
Usage:
@ModulePublic
@POST
@RestRequest
(description=
"Create a book"
,
properties= {
@RestObjectProperty
(name=
"Title"
, description=
"Title of the book"
, required=
true
, sampleValue=
"Learning Platform"
),
@RestObjectProperty
(name=
"Author"
, description=
"Author of the book"
, required=
false
, sampleValue=
"Greg Merrill"
)}
)
public
JSONObject createBook(JSONObject book) {
}
RestResponse
RestResponse is used to document response body. A collection of @RestObjectProperty annotations can be used inside a @RestResponse. It has the following attributes:
description: Provides a description about the parameter.
sampleValue: A sample value of the parameter.
RestObjectProperty[]: A collection of RestObjectProperty annotations to document response body properties.
Usage:
@ModulePublic
@GET
@RestResponse
(description=
"Get a book"
, sampleValue=
"{SysId:10000, Title:Learning Platform, Author:Greg Merrill}"
properties= {
@RestObjectProperty
(name=
"SysId"
, description=
"Unique identifier of the book"
, required=
true
, sampleValue=
"10000"
),
@RestObjectProperty
(name=
"Title"
, description=
"Title of the book"
, required=
true
, sampleValue=
"Learning Platform"
),
@RestObjectProperty
(name=
"Author"
, description=
"Author of the book"
, required=
true
, sampleValue=
"Greg Merrill"
)}
)
public
JSONObject getBook(
@QueryParam
(
"SysId"
)
@RestParam
(description=
"Unique identifier for a book"
, required=
true
, sampleValue=
"10000"
) Long sysId) {
}
RestEnumeration
RestEnumeration is used to document all enumerations used in the module. This annotation should be used only on the package-info.java file in the root folder of rest webservices (/rest). It takes a collection of fully qualified names of the enumerations.
Usage:
/**
* Web services for creating and retrieving books
*/
@com
.onenetwork.platform.integ.rest.annotation.RestEnumeration(enums={
"com.mybooks.model.enums.GenreEnum"
})
package
com.mybooks.rest;
RestException
RestException
RestException is used to document all exceptions that can be thrown by each web service. This annotation works differently when compared with the above discussed annotations.
@RestException should be used only on Exception classes, not on a REST resource. A resource that throws an exception which is annotated with @RestException will inherit the documentation from the Exception class.
It has the following properties:
errorCode: Provides an error code for the exception.
message: Provides an detailed message of the exception.
We will illustrate with an example.
We create an exception, called BookNotFoundException, which is thrown when the requested book is not found. We annotate this exception with @RestException annotation.
package
com.mybooks.rest;
import
com.onenetwork.platform.integ.rest.annotation.RestException;
@RestException
(errorCode=
"BookNotFound"
, message=
"Failed to retrieve the Book which corresponds to the provided id"
)
public
class
BookNotFoundException
extends
RuntimeException{
}
Now, we create a REST resource, shown below, which throws the BookNotFoundException. The documentation processor generates the error response documentation of this web service using errorCode and message defined in the BookNotFoundException's @RestException annotation.
@ModulePublic
@GET
public
JSONObject getBook(
@QueryParam
(
"SysId"
)
@RestParam
(description=
"Book Identifier"
, required=
true
, sampleValue=
"10000"
) Long sysId)
throws
BookNotFoundException{
// do something
}
Also, since @RestException annotation has a RetentionPolicy of RUNTIME, we will provide a response to the client during run time with errorCode and message defined on the BookNotFoundException if the web service throws BookNotFoundException.
@ModulePublic
@GET
public
JSONObject getBook(
@QueryParam
(
"SysId"
)
@RestParam
(description=
"Book Identifier"
, required=
true
, sampleValue=
"10000"
) Long sysId)
throws
BookNotFoundException{
try
{
// do something
}
catch
(RuntimeException ex) {
throw
new
BookNotFoundException();
}
}
You can also use inheritance for retrieving errorCode and message. Let's say a REST resource throws an exception, FictionBookNotFoundException, which is a sub class of BookNotFoundException. In this case, FictionBookNotFoundException is not annotated with @RestException annotation, but BookNotFoundException has the @RestException annotation. As a result, then errorCode and message of the error response is retrieved from the BookNotFoundException.
package
com.mybooks.rest;
import
com.onenetwork.platform.integ.rest.annotation.RestException;
public
class
FictionBookNotFoundException
extends
BookNotFoundException{
}
RestFooter
RestFooter is used to append additional text (including html markup) at the end of the generated documentation below the Enumerations section. (If there are no enumerations, then the text will be appended at the end of the web services section.) This annotation should be used only on the package-info.java file in the root folder of rest webservices (/rest). It takes a collection of file names that contain the text to be appended. The file name should provide the location of a file relative to the module's root directory. The order of appending file content depends on the order in which file names are declared on the annotation.
Usage:
/**
* Web services for creating and retrieving books
*/
@com
.onenetwork.platform.integ.rest.annotation.RestEnumeration(enums={
"com.mybooks.model.enums.GenreEnum"
})
@com
.onenetwork.platform.integ.rest.annotation.RestFooter(filenames={
"docs/RestFooter.txt"
,
"docs/Book.html"
})
package
com.mybooks.rest;
Note that if the file name provided in the RestFooter annotation is not found, a warning is displayed, as shown in the image below, in the ant console and the documentation is still generated.