We have an API built with Symfony that outputs its specification in the Swagger format. We needed to upgrade from version 1 to 2. As we switched the library to generate the specification while upgrading, we had to convert the configuration. In our case that configuration was so extensive that we decided to build a script to convert the configuration.
Swagger is a standard to document REST APIs. Using a JSON file, an application can document its API. Swagger specifies the path for each resource and allowed HTTP methods, as well as input parameters and the returned data. On top of this specification, tools like Swagger UI can automatically provide an API client in a browser. This is an excellent way to explore the documentation and also very helpful when investigating data issues.
We have been using NelmioApiDocBundle with our application for a while now. This bundle reads annotations on the controllers and combines them with the Symfony routing informations to produce an API documentation in the Swagger 1 format. Support for Swagger version 2 however was not available in NelmioApiDocBundle at the time of this blog post. We would have stayed with NelmioApiDocBundle, as it worked well for us, but we did not want to invest the time to refactor that bundle to Swagger 2.
For the consumers of our Swagger json files, we had to migrate to the new version 2 of Swagger. We chose to switch to Swagger-PHP that is capable of generating Swagger 2. It also uses PHPDoc annotations for the additional meta information. As we have about 100 paths (Symfony actions in our case), we decided to write a converter rather than rewrite all of this by hand. The converter is available as Symfony command – of course without any warranty.
To replace the browser view of NelmioApiDocBundle, we use the SwaggerUiBundle. That bundle only handles displaying, but has no integration with Swagger-PHP to generate the Swagger json.
During the transition, we discovered some drawbacks of Swagger-PHP where NelmioApiDocBundle is more convenient:
- NelmioApiDocBundle reads the Symfony route definition. With Swagger-PHP you need to duplicate that information into the swagger annotations:
- Route path
- HTTP methods (GET / POST / …)
- Path parameters with their restrictions and description from the PHPDoc '@param'.
- Swagger-PHP uses the local class names of models for the schema name if no name is explicitly specified. This forces us to manually specify schema names for models from different namespaces that have the same local name.
- Swagger-PHP does not use PHP to read the annotations but instead parses the PHP code itself. This makes for some hard to read parser code, should you ever want to fix a bug or extend the library.
Most of the redundancy in the annotations is due to Swagger-PHP not knowing about Symfony. Maybe a SwaggerPhpBundle would be a worthwile effort. Or even better, merge the efforts of NelmioApiDocBundle with Swagger-PHP to have one good library that supports Swagger 2.
- Symfony command we wrote to convert from NelmioApiDocBundle to Swagger-PHP