-
Notifications
You must be signed in to change notification settings - Fork 97
SwaggerDescriptorService
Starting with 0.7.5 a ServiceHost can describe all deployed services using Swagger 2.0. The descriptor itself is served by a stateless service.
Stateful services will by default have their own service and their factory service included in the generated swagger documentation. The default factory service has documentation annotations provided for it.
Stateless services are also included in the generated swagger documentation.
This service is started as any other on a host:
SwaggerDescriptorService swagger = new SwaggerDescriptorService();
// provide general API info
Info info = new Info();
info.setDescription("description");
info.setTermsOfService("terms of service etc.");
info.setTitle("title");
info.setVersion("1.0");
swagger.setInfo(info);
// option to exclude some services by prefix
swagger.setExcludedPrefixes("/core/authz/");
// option to exclude utility services
swagger.setExcludeUtilities(true);
// option to simplify names of REST resources by stripping package
// prefixes from REST resource names (can be a list of strings)
swagger.setStripPackagePrefixes("com:vmware:xenon:common:");
// option to specify filtering of RESTful paths by their documented
// support level - if set, only include routes which have a support
// level equal to or higher than the given level. SupportLevels are
// NOT_SUPPORTED, INTERNAL, DEPRECATED, PUBLIC.
swagger.setSupportLevel(PUBLIC);
host.startService(swagger);
The swagger service uses the information from each service's documentDescription
to generate the swagger description.
The easiest way to add this information to a service is via the use of
Java annotations on the fields of the ServiceDocument
and optionally
on the route handler methods.
The service document itself and each field in the service document can
have documentation added to it via the @Documentation
annotation. Here is an example:
@Documentation(description = "name field", exampleString = "myExample")
public String name;
The exampleString
fields are used to construct example JSON in the
swagger UI. It's good practice to provide a reasonable example value -
if there isn't one, a default value will be provided.
If a field is itself a PODO data structure, then each field within that PODO data structure may be annotated.
When a field is a collection of simple types, then the exampleString
can contain a JSON fragment
with an example of the serialized JSON for that collection, for example:
@Documentation(description = "@TAGS", exampleString = "{ \"tag1\" , \"tag2\" }")
public Set<String> tags;
Note the value of the description field here is @TAGS
- see the section below.
By default, all routes described by the ServiceDocument
will be included in the swagger documentation.
A route may have additional documentation added to it via the use of
the @RouteDocumentation
annotation. Here is a simple example:
@RouteDocumentation(description = "@PUT")
public void handlePut(Operation put) {
...
}
This provides a description of the route. The description field starts with '@', this is a convention to indicate that the complete description comes from a supporting HTML resource file (see below).
There are many parameters which can be documented about a given resource route:
The support level of this route. This can be used to filter out which routes are included in the swagger documentation, initialized when configuring the swagger service.
By default PUBLIC
. May be one of: NOT_SUPPORTED
, INTERNAL
,
DEPRECATED
, PUBLIC
.
The route's description. May be a token indirecting to a more complete description in a supporting HTML resource file (see below).
A list of possible HTTP response codes, each with a possible description and response body type.
A list of supported query parameters, each with name
field and
optional description
, type
, example
and a boolean required
fields.
A list of supported media types for the request, defaulting to application/json
A list of supported media types for the reseponse, defaulting to application/json
Lengthy descriptions in java source files rapidly makes the java become hard to read.
Any description
field in a @Documentation
or @RouteDocumentation
annotation may refer to a more complete description found in a
supporting HTML resource file - this allows richer descriptions to be
written directly in HTML, and be included in the swagger documentation.
By convention we start such descriptions with an '@
' sign to
indicate that they are a reference.
The supporting HTML resource file must be found in the java classpath
in the same directory as the java class, and with the same name other
than an .html
suffix instead of the .class
suffix.
The HTML file format is expected to have each description key on its
own line surrounded with <h1>
and </h1>
header tags. All the
content of the file until the next line starting with an <h1>
header
tag will be included as the description value.
An example might look like this:
@RouteDocumentation(description = "@PUT")
public void handlePut(Operation put) {
...
}
@RouteDocumentation(description = "@PATCH")
public void handlePatch(Operation patch) {
...
}
<!-- Documentation file for ExampleService -->
<h1>@PUT</h1>
Overwrite example document with new copy
<h1>@PATCH</h1>
Update selected fields of example document
Note that inside the HTML resource file, the description body may contain HTML eg. may contain a table or list. Having this in an HTML file makes editing of such text easier than inline in a quoted string in a java file.
/discovery/swagger
The descriptor is available at /discovery/swagger. It can be retrieved in JSON or YAML format depending on the "Accept" header.
SwaggerUI is deployed as custom UI of the stateless service. It is available at /discovery/swagger/ui.
There are not equivalents for all swagger annotations
currently. Support is being added on an as-needed basis. Please
contact the #xenon
slack channel.
The reason chosen not to directly use swagger anntoations in the
service itself was to avoid a core dependency on swagger, to avoid one
service needing to introspect another service's class files, and to
support the programatic inclusion of resource documentation via the
resource's documentDescription
and thus not requiring the use of
annotations. In any case, the swagger service needs support for the
given swagger functionality in order to generate a suitable document.