Making an uber minimal API

API’s or ‘Application program interface’ are simply ways to handle requests, usually such that the responses are consistent and easy to interpret. This is an essential building block in services that bridge different providers such as the google maps API, or in a microservice architecture such as Netflix.

In its most basic form:

1. A user (usually programmatically) sends a http request to the host server. The url args contain the details of the ‘task’ the user has specified.

2. The server parses the url args and performs its required task.

3. The server responds with an output in a machine friendly format, e.g: JSON.

This is effective as the method through which the user interacts with the service is not confined to any one program, language or OS. This allows developers to integrate external services such as Instagram into their applications, without Instagram having to relinquish control over what external parties can control. So while I could make a service allowing a user to like an Instagram post, I can’t go and delete their databases.

First item on the agenda — Somewhere to send a request:

Probably a good start. Flask can be used to create a very tidy application for this.

from flask import Flask, request, jsonify
app = Flask(__name__)
@app.route('/api')
def API():
return process_request(request.args) #get URL arguments
if __name__ == "__main__":
app.run(debug=True)

Next — Make it do something!

For the sake of example, this function calculates BMI when given weight, height and optionally sex.

def get_BMI(height, weight, sex='male'):
#Calculate BMI and BMI category:
    #Some maths here
    #return a dict which will be converted to JSON
return {"BMI": BMI, "category": category,
"data": {"height": height, "weight": weight, "sex": sex}}

It returns a dictionary which can be converted to JSON for ease of use by the receiving party. The process_request function ensures that the required arguments are present and throws an error if not.

def process_request(query):
if 'height' in query.keys() and 'weight' in query.keys():
if 'sex' in query.keys():
response = get_BMI(query['height'],
query['weight'],
sex=query['sex'])
else:
response = get_BMI(query['height'],
query['weight'])
else:
response = {"error": "'height' and 'weight' are required"}

return jsonify(response)

Now a user can pass a a url in the format: ‘http://www.hostsite.com/api?weight=67&sex=female&height=172 and receives a response in JSON:

{
"BMI": 20.74506939371804,
"category": "Healthy",
"data": {
"height": "185",
"sex": "male",
"weight": "71"
}
}

Yay, your API works!

Bonus round — make it nicer to use:

While concatenating strings into a url to then send a GET request, then convert the response to JSON before finally being able to access your output is possible, organisations often release libraries or packages to make this process much more user friendly. By hiding the mechanics in a package, APIs can become a bit of a ‘black box’ but this also drastically decreases the barriers to using your service. A simple python class can take care of it in this case:

class Bmi(object):
def __init__(self):
self.BMI = 'no data'
self.category = 'no data'
    def get(self, weight, height, sex="male"):
import urllib2
import json
        url = 'http://www.hostsite.com/api?'      
query = 'weight='+str(weight)
query += '&height='+str(height)
query += '&sex='+sex
response = urllib2.urlopen(url + query)
data = response.read()
data = json.loads(data)

self.BMI = data["BMI"]
self.category = data["category"]

Now the interaction with the API is a lot more ‘human’.

from bmi_package import bmi
test = bmi.Bmi()
test.get(89, 185)
print(“Your BMI is: {0}”.format(test.BMI))
print(“Based on this, you are: {0}”.format(test.category)

This story is published in The Startup, Medium’s largest entrepreneurship publication followed by 285,454+ people.

Subscribe to receive our top stories here.

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.