Description-Agnostic API Development with API Transformer

APi-transformer-01

Whilst many aspects of the API economy are subject to discussion and conjecture, if there is one truth it’s this: When it comes to successfully describing your API, the jury is out on the best tool for the job. As the API economy has grown so has the number of API description specifications, each with their own specific format and supporting tools. The fact that Swagger has been chosen by the Linux Foundation to be the formative standard for the Open API Initiative might indicate that Swagger will become even more prevalent, but given the investment by organizations in a particular specification choice there is unlikely to be a homogenous approach adopted across the industry any time soon.

Alongside this dialectic, the increasing popularity of the API-first design approach is making API description specifications more fundamental to the development process. API specifications are becoming the product of design, generated by prototyping tools such as RAML Designer, API Blueprint, Readme.io, or Swagger Editor, with both the documentation and a mock-up available before the developer starts coding. This is a departure from the retrospective method of description that has generally prevailed until recently, where the developer annotates code or manually produces a schematic representation of the API to convey their design. In contrast, API-first design strives to optimize the API expressly for its own goals, purposefully ignoring organizational constraints, architectures and programmatic conventions to create an API definition that exactly meets its design intention and requirements. However, the API-first design principle may also result in technology lock-in for development teams, binding developers to a given set of tools and programming languages that support the chosen specification format.

Where API Transformer Fits

The evolution of the API design and development process is one of the reasons why the API Transformer, created by APIMATIC is an interesting development. API Transformer provides a tool, the “Convertron” that makes it easy for developers to convert from one API specification format to another, supporting the majority of popular API specifications including major Swagger versions, RAML, and WADL. API Transformer provides a web UI that a developer can use to convert an existing specification to an alternative format simply by completing the required fields:

API Transformer - HomepageHowever, the real power of Convertron is that it also provides a simple API, providing the same functionality as the UI in a manner that can be used programmatically. The example below is a cURL command that converts a Swagger 2.0 specification, the Swagger-provided pet store example to RAML:

curl -o petstore.raml -d 'url=https://raw.githubusercontent.com/swagger-api/swagger-spec/master/examples/v2.0/json/petstore.json' https://apitransformer.com/api/transform?output=raml

This functionality makes several interesting use cases possible:

  • It allows developers to choose the API specification that makes most sense to them or can be consumed by their favorite development tools, meaning design and development teams have greater flexibility;
  • An API provider can also offer API specifications for download from their developer portal in a variety of formats, which may be helpful to the developer community and increase engagement by communicating to them in a way they understand;
  • An API provider can extend the coverage of their testing, by testing against generated formats to ensure there are few semantic differences between one format and another, providing greater resilience in the development process;
  • Finally, API providers can also easily migrate away from “legacy” description specifications to ones with better support e.g. WADL.

Example Use Case

In order to test the use cases above we took the concept of a developer portal where API Transformer is used to create translations of an API description. The API provider that owns the developer portal in this use case specifies their APIs using Swagger, and publishes the specification in different formats as as a convenience to the developer community. In this scenario we envisaged this being a facet of the development process, embedded in continuous integration: When code is published to the git repository for the API, a process is executed that creates translations of the Swagger description in several pre-defined formats. The steps in the process are:

  • Developers push code changes to the git repository for the API;
  • The CI server detects the commit and spins up an instance of the API, checking to see if the Swagger JSON had changed;
  • If a change is detected a Gherkin-style test suite is executed against the API;
  • On successful completion of the test suite a version of the specification is generated in the alternative formats the API provider makes available. This is staged ready to be pushed in a CDN to populate the portal.

To demonstrate this we’ve created a working prototype in Python and Jenkins, the configuration being available on GitHub. Firstly, we created a very simple API using Flask-RESTPlus, describing the API using the Swagger-based syntactic sugar that Flask-RESTPlus offers:

from flask import Flask
from flask.ext.restplus import Api, Resource, fields
from uuid import uuid4

app = Flask(__name__)
api = Api(app,
          version="1.0",
          title="API Transformer demonstration",
          description="API created to demonstrate the functionality offered by the API Transformer Convertron")
demo_ns = api.namespace('demo', description='Demo operations')


@demo_ns.route('')
class Demo(Resource):
    @api.doc(description='A demo HTTP GET',
             responses={400: ("Bad request", api.model('Error', {"message": fields.String})),
                        500: "Unhandled exception (captured in server logs)"})
    def get(self):
        return 'This is a demo!', 200

    @api.expect(api.model('Demo Request', {"data": fields.String(required=True)}))
    @api.doc(description='A demo HTTP POST',
             responses={400: ("Bad request", api.model('Error', {"message": fields.String})),
                        500: "Unhandled exception (captured in server logs)"})
    @api.marshal_with(api.model(
        'Demo Response',
        {"id": fields.String(required=True), "data": fields.String(required=True)}), code=201)
    def post(self):
        return {'id': uuid4().hex, 'data': 'Created new demo resource'}, 201

if __name__ == '__main__':
    app.run(port=8080, debug=True)

Download our free development guideFor the purpose of brevity we then created a simple job that triggered when a commit was made to a local git repository (in reality we would obviously add the test suite and check for content changes for each new version). When triggered, a shell script build step is executed that initializes an instance of our demo API, downloads a copy of the Swagger JSON, and then loops through our target alternative format types:

# Loop through formats and transform
for format in raml "api%20blueprint" "apimatic" ; do
    ext=$(echo $format|tr " " "_")

    # Curl for each target format
    echo "info: Generating spec for ${format}"
    curl -X POST "https://apitransformer.com/api/transform?output=$format" \
    -o $WORKSPACE/transformer_output/app.${ext} -H "Content-Type: text/plain" -d @$WORKSPACE/swagger.json

    if [[ $? -ne 0 ]] ; then echo "error: Failed to generate spec" && exit -1; fi

done

On successful execution new translations of the Swagger specification are generated in RAML, APIMATIC and API Blueprint formats and saved in the job workspace. The new versions of the specification are pushed to an S3 bucket (using the S3 Plugin, ready to be referenced by a CloudFront distribution.

API Transformer - S3 BucketConclusion: The Value of API Transformer

transformerThere is no doubt that API Transformer offers a useful prospect for API designers and developers to help them quickly convert an API from one description specification to another. Further due diligence and testing on the part of the developer community will ascertain whether any semantic differences exist between source specifications and any of the targets that API Transformer generates, and this will prove its value as a tool for the API community.

We’ll continue to use and review API Transformer and offer further insights on it and comparable tools that are introduced to the marketplace.