Just getting started with using Swagger-Core Annotations on some JAX-RS services (using Jersey implementation).
Using the JerseyJaxrsConfig servlet to generate swagger.json. Using swagger-ui to see a "pretty" version of the annotations. (Using sample ApiOriginFilter to solve CORS issues.)
Pretty happy so far, but wondering how to tweak things in a few cases.
First, my setup:
I have this class/service:
/** REST web services for getting vocabularies. */
@Path("/api/resource")
@Api
public class GetVocabularies {
/** Get all the current vocabularies.
* @return The list of vocabularies, in either XML or JSON format. */
@Path("vocabulary")
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
@GET
@ApiOperation(value = "Get all the current vocabularies.")
public final List<Vocabulary> getVocabularies() { ... }
...
}
The Vocabulary class is generated using xjc from an XML Schema. So it has many JAXB annotations: @XmlRootElement , @XmlType, and @XmlAccessorType on the class, and @XmlElement/@XmlAttribute on the fields.
There is also a package-info.java file generated, which contains this:
@javax.xml.bind.annotation.XmlSchema(namespace = "
http://vocabs.ands.org.au/registry/schema/2017/01/vocabulary", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
package au.org.ands.vocabs.registry.schema.vocabulary201701;
So ... that all generates the following fragments in swagger.json:
"/api/resource/vocabulary" : {
"get" : {
"operationId" : "getVocabularies",
"parameters" : [],
"responses" : {
"200" : {
"description" : "successful operation",
"schema" : {
"items" : {
"$ref" : "#/definitions/Vocabulary"
},
"type" : "array"
}
}
},
"summary" : "Get all the current vocabularies.",
"produces" : [
"application/xml",
"application/json"
],
"description" : ""
}
},
and:
"Vocabulary" : {
"properties" : {
"title" : {
"xml" : {
"attribute" : true
},
"type" : "string"
},
...
"xml" : {
"name" : "vocabulary"
},
...
"type" : "object"
}
Now to my "issues", which are related to how swagger-ui presents the "Example Value" for XML.
Issue #1: XML wrapper element for the List<...>.
The "Example Value" looks like this:
<?xml version="1.0"?>
<vocabulary id="1" status="PUBLISHED" owner="string" slug="string" title="string" acronym="string" description="string" note="string" revision-cycle="string" creation-date="string" primary-language="string" licence="string">
...
But in fact what comes back from the service is (some content replaced with "..." where it's not relevant):
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<vocabularies>
<vocabulary xmlns="http://vocabs.ands.org.au/registry/schema/2017/01/vocabulary" id="1" status="published" owner="..." slug="..." title="..." acronym="..." description="..." revision-cycle="..." creation-date="..." primary-language="en" licence="CC-BY">
...
So there is a JAXB-generated "wrapper" element <vocabularies> around the list. (For lists like this, JAXB automatically generates a plural form of the XML element name during serialization. In this case, the generated plural form is correct ....)
I can get that to appear in swagger-ui's "Example Value" by saving the generated swagger.json and then editing it to add "xml" data so that it says:
"/api/resource/vocabulary" : {
"get" : {
"operationId" : "getVocabularies",
"parameters" : [],
"responses" : {
"200" : {
"description" : "successful operation",
"schema" : {
"items" : {
"$ref" : "#/definitions/Vocabulary"
},
"type" : "array",
"xml": {
"wrapped" : true,
"name" : "vocabularies"
}
}
}
},
"summary" : "Get all the current vocabularies.",
"produces" : [
"application/xml",
"application/json"
],
"description" : ""
}
},
Issue #2: XML namespace for the Vocabulary.
The Example Value doesn't include the XML namespace for the Vocabulary element. It seems the @XmlSchema annotation in package-info.java is not taken into account.
Again, I can fix that thus in my modified swagger.json:
"Vocabulary" : {
"type" : "object",
"xml" : {
"name" : "vocabulary",
"namespace" : "
http://vocabs.ands.org.au/registry/schema/2017/01/vocabulary"
},
...
}
After making both modifications, the Example Value in swagger-ui now looks like this:
<?xml version="1.0"?>
<vocabularies>
<vocabulary xmlns="http://vocabs.ands.org.au/registry/schema/2017/01/vocabulary" acronym="string" slug="string" note="string" status="PUBLISHED" creation-date="string" revision-cycle="string" title="string" primary-language="string" id="1" owner="string" licence="string" description="string">
<top-concept>string</top-concept>
...
and this is correct.
Issue #3: values of enumerated types.
Well, not quite correct. I just noticed that the values of enumerated types are wrong. As you see, the correct values of the "status" attribute are in lowercase, and the Example Value gives an uppercase value. I could edit the values in the "enum" section of swagger.json to fix that. But the correct values are already in the generated enum class as annotations, e.g., @XmlEnumValue("published"). It seems they are not being used. (Note: for JSON, the service (via Jackson) returns the values in uppercase, so the JSON Example Value is correct! Confusing, slightly annoying, and something I may want to do something about!)
So my question: can I add more/modify existing Swagger-Core Annotations or otherwise modify my code so that the "correct" swagger.json is produced in the first place?
Richard.
--
Richard Walker
Australian National Data Service (ANDS)
101 Liversidge Street
The Australian National University
Acton ACT 2601, Australia
E:
Richard...@ands.org.auT:
+61 2 6125 0584W:
www.ands.org.au