API First Strategy with Connexion

Radek Stankiewicz
Radoslaw Stankiewicz Desk
5 min readJun 1, 2016

--

I’ve heard about “API First” some time ago on Kin Lane’s apievangelist.com blog. In few words it means discuss and design API contract first, then implement code. Why it’s important?

SOA world

I‘ve spent some time in SOA world where it’s nothing new. You had to design CDM first, create WSDL, then start implementing WS with your favourite Enterprise boxes (mine is WebSphere Message Broker). Designing CDM was a long process, requiring hours of discussion with systems analysts to understand what data systems provide. It has to be designed first because changing schema is really painful for many parties when it is up & running. In my case it was painful:

  • as a service creator, because it requires regeneration of code, fixing namespaces and you need to deprecate & slowly shut down older versions
  • as a service consumers, because regeneration of schema may break the code and introduce delays in the project.

RESTful world

When I moved from building hundreds of services to Restful APIs I was amazed how easily one can code, ship and use APIs, but over time, it became apparent that I need as well an easy way of documenting it.

There are plenty of tools already that can generate OpenAPI spec based on the source code, I’ve listed few of them here, but it’s not an API first approach I wanted to try.

As a developer by heart, it was difficult for me to follow a rule “Before you build you design an API first, then you get to code”. Until I found Connexion.

Connexion

With Connexion framework you write OpenAPI spec first using notepad or swagger-editor until it’s ready, then you use this specification as an input to framework. You can read more about it here.

Specification first

Let’s create hello-world service that will in-memory store and list Hello’s. We start with general information and definitions of Hello object.

swagger: "2.0"
host: 127.0.0.1:5000
info:
title:
hello
version: "1.0"

basePath:
/v1.0

definitions:
Hello:
type:
object
properties:
hello_id:
type:
string
name:
type:
string
time:
type:
string
format: date-time
required:
- name
- time

We then want to create service that will enable us to post hello.

paths:
'/hello':
post:
parameters:
- in: body
name: hello
required: true
schema:
$ref: '#/definitions/Hello'
responses:
'201':
description: 'Submitted a Hello'

Notice reference to Hello definition. We save file as api.yaml.

You can find whole api.yaml file here, I’ve added all other methods there.

Implementation second

We create project structure as follows:

project structure

Let’s start with requirements.txt file:

connexion
tornado
Flask==0.10.1
Werkzeug==0.10.4

and very simple main where we specify api specification.

if __name__ == '__main__':
app = connexion.App(__name__)
app.add_api('api.yaml', resolver=RestyResolver('api'))
app.run() # will run on 127.0.0.1:5000

RestyResolver make it easier to split API functionality into modules, that way that if we have/resource then under api package we add resource.py module with all methods required for each method (e.g. GET /resource is mapped automatically to resource.search(), POST /resource is mapped to resource.post(param) etc).

Our POST /hello will look then as follows:

import datetime
from connexion import NoContent
hellos = {}


def post(hello):
hello_id = str(uuid.uuid4())
hello['time'] = datetime.datetime.now()
hello['hello_id'] = hello_id
hellos[hello_id] = hello
return NoContent, 201

You can find whole hello.py file here, I’ve added all other methods there.

Testing third

Connexion framework is bundled with swagger-ui that enable very fast verification. You can find it under /v1.0/ui address.

Rest Secured security testing

Disclaimer: I’m co-founder of Rest Secured.

To test security of this API I push it to Heroku, I take swagger url (http://fierce-oasis-26736.herokuapp.com/v1.0/swagger.json), and I paste it in Rest Secured service.

Input to Rest Secured

It requires only OpenAPI specification to run a security scan, it automatically detects endpoints and estimates amount of test cases it will run against it.

Statistics

Whole scan takes few minutes to finish, depending in size of your API and amount of parameters and presents alerts that require review. It using exploratory techniques that can help find unknown issues and follows OWASP Top 10.

Security report

There were some issues found:

  • One is related to OpenAPI input validation that accepts more date formats than I expected — querying with “2016–06–01T19:36:41Z” results with 500 Internal Server Error.
Encoding issues
  • Second interesting one is related to UTF8 coding — calling with binary input or /v1.0/hello/%C5%BA%C4%87%C5%B which is źćż breaks framework — It requires more investigation in Connexion framework.
  • Other issues are more related to Heroku platform which we can ignore now.

Summary

I’m very happy I found Connexion framework — it saved me some time and I believe it will save lots of it in the future.

Features I like the most:

Whole project is available on GitHub with some added features that will help you push it to Heroku.

--

--

Strategic Cloud Engineer at Google Warsaw - Helping customers solve their biggest data & analytics challenges using the best of Google.