Skip to content

1.3 1.5 Migration

frantuma edited this page Mar 2, 2016 · 10 revisions

Migration Guide from Swagger-Core 1.3 to 1.5

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.


Dependencies

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.

Structure and Hosting

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.

JAX-RS Providers

In 1.5, you need to expose one provider:

  • io.swagger.jaxrs.listing.SwaggerSerializers - this provides a custom MessageBodyWriter for the Swagger 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.

Annotations

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.

Operation Grouping

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.

Using web.xml and BeanConfig

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.

Setting up additional information (authorization, info)

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("apiteam@swagger.io"))
      .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.

Conclusion

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.

Clone this wiki locally