-
Notifications
You must be signed in to change notification settings - Fork 2.2k
1.3 1.5 Migration
This guide is going to contain various points of consideration when migration from swagger-core 1.3 to swagger-core 1.5.
While we've taken measures to keep 1.5 backwards compatible as much as possible, there are still a few modifications that need to be made in order to produce a Swagger 2.0 definition.
Further changes can be made to the code to take advantage of some of the new Swagger 2.0 features. This guide will try to cover those as well.
While it may be confusing, keep the following in mind:
swagger-core 1.3 produces Swagger 1.2 definitions. swagger-core 1.5 produces Swagger 2.0 definitions.
Since swagger-core 1.5 contains implementation for JAX-RS only, this guide covers the migration for that alone. Play integration would be handled at a later date.
As part of the 1.5 release, we've repackaged the project under the io.swagger package. If you're migrating, you need to update your imports accordingly. This will mostly affect your annotation usage. A simple find/replace should cover this change easily.
The groupId in maven has also changed to io.swagger
.
swagger-core 1.5 was developed using Java and not Scala. As a result, the dependency names have slightly changed. In 1.3, we attached the Scala version to the dependency, so we had something like swagger-jaxrs_2.10
. Since that's no longer required, the dependency name would change to simply swagger-jaxrs
. This is true for all the dependencies provided by the project.
Remember, the maven groupId
has also changed to io.swagger
.
Swagger 2.0 employs a new file structure where all the information is provided in a single file, unlike the split file definitions in older versions of the spec. On top of that, Swagger 2.0 can be represented with either JSON or YAML.
In swagger-core 1.3, the main Swagger definition was exposed by /api-docs
hosted at the context root of your application. If the context root was /myapp
then to reach the Swagger definition you'd go to http://{host}/myapp/api-docs
.
Swagger-core 1.5 still exposes the definition under the context root, but with the name /swagger.json
or /swagger.yaml
. So now you'd go to http://{host}/myapp/swagger.json
or http://{host}/myapp/swagger.yaml
.
In 1.5, you need to expose one provider:
-
io.swagger.jaxrs.listing.SwaggerSerializers
- this provides a customMessageBodyWriter
for theSwagger
object, customizing the serializtion to JSON and YAML formats.
In addition, this resource is required:
-
io.swagger.jaxrs.listing.ApiListingResource
- this provides the/swagger.json
and/swagger.yaml
endpoints.
Resource io.swagger.jaxrs.listing.AcceptHeaderApiListingResource
is required to provide /swagger
with Accept header application/json
or application/yaml
Alternatively, if you use package scanning for providers, you can just specify io.swagger.jaxrs.listing
.
In 1.3, there were specific providers for specific JAX-RS variants (general, Jersey 1, Jersey 2). This is no longer the case as the specific implementations are provided via plugins. These providers were known as ApiDeclarationProvider
, ResourceListingProvider
, JerseyApiDeclarationProvider
, JerseyResourceListingProvider
, ApiListingResource
, AcceptHeaderApiListingResource
, ApiListingResourceJSON
, JacksonJsonProvider
.
The annotations in 1.5 remain largely the same. There are a few additions and some usages have become obsolete or changed.
You should not need to make any changes to your annotation, unless you want to take advantage of some of the new aspects of Swagger 2.0. This should ease the transition from 1.3 to 1.5.
In Swagger 1.2 operations were grouped under resources which normally translate to JAX-RS resource classes. This was the behavior in swagger-core 1.3.
Swagger 1.5 employs a different grouping mechanism that is based on tags. Fear not, as even if you move to swagger-core 1.5, your operations would be grouped as before in the same 'resource' structure. The @Api#value()
will be used for the tag, after stripping out the leading slash. If you want to control it further, you can use either @Api#tags()
to affect all operations under it, or @ApiOperaation#tags()
to affect an individual opeartion. Unlike the previous version, an operation can have multiple tags, and as such tags()
is an array.
Whether you use DefaultJaxrsConfig
in your web.xml or BeanConfig
in your bootstrap / as a Spring bean, the basic configuration remains the same and you should not need to make changes for it to work.
BeanConfig
got a few additional entries for more control, but largly it remains the same. It now contains the following:
Method | Property Name | Purpose |
---|---|---|
setTitle(String) | title | Sets the title of the application. |
setDescription(String) | description | Sets the description of the application. |
setTermsOfServiceUrl(String) | termsOfServiceUrl | Sets the URL of the application's Terms of Service. |
setContact(String) | contact | Sets the contact information for the application. |
setLicense(String) | license | Sets the license of the application. |
setLicenseUrl(String) | licenseUrl | Sets the licesne url of the application. |
setVersion(String) | version | Sets the version of the API. |
setSchemes(String[]) | schemes | Sets the schemes for the API URLs (http, https). |
setHost(String) | host | Sets the host (including a port) for the API URLs. Does not include the schemes nor context root. |
setBasePath(String) | basePath | Sets the context root for the API calls. |
setFilterClass(Sting) | filterClass | Sets a security filter for Swagger's documentation. |
setResourcePackage(String) | resourcePackage | Sets which package(s) Swagger should scan to pick up resources. If there's more than one package, it can be a list of comma-separated packages. |
setScan(boolean) | scan | When set to true , Swagger will build the documentation. |
setPrettyPrint(boolean) | prettyPrint | Sets whether the swagger.json will be pretty printed. |
One major difference between Swagger 1.2 and 2.0 (swagger-core 1.3 and 1.5 respectively) is that the basePath
which used to be a full URL is now split into three components - schemes
, host
and basePath
.
schemes
corresponds to the protocols (http, https), host
is the host/ip address + port and basePath
is the context root. Unlike in the past, none of these are mandatory anymore and a default value would be assumed. For schemes
and host
, the default is the same scheme and host used to access the swagger.json
or swagger.yaml
files. This is especially convenient when deploying to different environments. If basePath
is not specified, it would default to the root directly under the host.
This does not require you to change the the value of BeanConfig.setBasePath()
. If you input a full path there, it would be broken down and split to the three values for you.
In swagger-core 1.3, you could use the ApiInfo
and AuthorizationType
classes to set up additional information and authorization for your API. You'd then use the ConfigFactory
to save it and have it served.
This behavior has changed completely in swagger-core 1.5 and needs to be rewritten in order to be used.
In swagger-core 1.5, we utilize the Swagger class which is a direct representation of the output. Considering the following code sample:
public class Bootstrap extends HttpServlet {
@Override
public void init(ServletConfig config) throws ServletException {
Info info = new Info()
.title("Swagger Sample App")
.description("This is a sample server Petstore server. You can find out more about Swagger " +
"at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, " +
"you can use the api key `special-key` to test the authorization filters.")
.termsOfService("http://helloreverb.com/terms/")
.contact(new Contact()
.email("[email protected]"))
.license(new License()
.name("Apache 2.0")
.url("http://www.apache.org/licenses/LICENSE-2.0.html"));
ServletContext context = config.getServletContext();
Swagger swagger = new Swagger().info(info);
swagger.externalDocs(new ExternalDocs("Find out more about Swagger", "http://swagger.io"));
swagger.securityDefinition("api_key", new ApiKeyAuthDefinition("api_key", In.HEADER));
swagger.securityDefinition("petstore_auth",
new OAuth2Definition()
.implicit("http://petstore.swagger.io/api/oauth/dialog")
.scope("read:pets", "read your pets")
.scope("write:pets", "modify pets in your account"));
swagger.tag(new Tag()
.name("pet")
.description("Everything about your Pets")
.externalDocs(new ExternalDocs("Find out more", "http://swagger.io")));
swagger.tag(new Tag()
.name("store")
.description("Access to Petstore orders"));
swagger.tag(new Tag()
.name("user")
.description("Operations about user")
.externalDocs(new ExternalDocs("Find out more about our store", "http://swagger.io")));
context.setAttribute("swagger", swagger);
}
}
Notice that this is a Servlet that needs to be loaded (not served) with your application. We use the ServletContext to host the swagger
attribute. This is a step crucial for swagger-core to pick up your configuration.
The info
structure has changed in 2.0, and is described above. Remember that some fields are mandatory and you can check out specification itself to see what those are. The BeanConfig
method still allows you to set all the required fields without going through this process.
Adding a new securityDefinition
(used to be AuthorizationType
) is simplified. Just follow the process from the example above.
One addition is the Tag
. As explained in a previous section, grouping is now done using tags. While tags are generated automatically as they are declared, you may wish to add more information on the tags. You can set a description
(which in 1.3 was automatically derived from the code, but no more) and you can add additional information in a form of external documentation.
Once completing the steps above, you would have your Swagger 2.0 definitions generated. The straightforward process should take about 15-20 minutes to complete. Once that's done, you can choose whether you want to fine-tune your Swagger 2.0 experience and utilize a few more aspects of it, but the migration itself would be done.