A Proper API Crash Course

James Gibson

slides.com/jamesgibson-3/deck/live

Who am I?

  • Senior Software Engineer at Apto
  • 4 years software engineering, 11 years programming
  • Twitter: @brainchildpro
  • Github: james-gibson
  • Denver Devs Slack: james.the.nodester

API Credentials

  • Self-hosted home automation software
  • Built and maintained a worldwide energy usage dashboard for the US NAVY
  • Migrated a v0 to v1 for an indoor location analytics software
  • Consulted on skunkworks API design for a Fortune 25 company

Let's define a few things

Wikipedia defines an API as:


In computer programming, an application programming interface (API) is a set of routines, protocols, and tools for building software applications. An API expresses a software component in terms of its operations, inputs, outputs, and underlying types.

In practice, an API is: 

Getting system A to do work for system B

What do you mean "Do work"?

An API can provide:

  • Detailed weather forecasts (forecast.io)
  • In-depth directions (Google Maps)
  • New music (Soundcloud)
  • House listings (Zillow)

What do you mean "Do work"?

An API can provide:

  • Control over your entire production deployment (EC2)
  • Insight into natural language (Alchemy API)
  • Access to a self-service AI (Watson)

So API's are awesome, right?

Not always!

Not all API's are created equal

You may have the chance to work on really well designed API's, but...

You will more then likely have to work on really bad API's

Choose your destiny

credit: Dann Stockton & David Stockton

Choose your destiny

Sounds great, 

where do we start?

Avoid the common pitfalls

Many common mistakes occur simply due to lack of experience

Every ms that your request takes is time that adds up for the end user.

Not every developer has the same level of restrictions that you do.

Some platforms impose timeout limits that cannot be raised.

    Eating up transaction time with requests is a generally easy

problem to fix.

What could possibly go wrong?

function verifyUserKey(req, res, next) {
    var userId = req.query.userId,
        key = req.query.key,
        token = authModel.getToken(userId,key);

    if(!token) { return res.json({message:"Invalid User and Key"}); }

    req.token = token;

    next();
}

Fail fast, fail hard...

function verifyUserKey(req, res, next) {

    //Fail before making database calls
    var userId = req.query.userId,
        key = req.query.key;

    if (typeof userId === "undefined" || typeof key === "undefined") {
        return invalidCredentials();
    }

    req.token = authModel.getToken(userId,key);

    if(!req.token) {return invalidCredentials();}

    next();

    function invalidCredentials() {
        res.json({message:"Invalid User and Key"}); 
    }
}

Validate inputs early

..but fail gracefully!

function verifyUserKey(req, res, next) {
    var userId = req.query.userId,
        key = req.query.key;

    if (typeof userId === "undefined" || typeof key === "undefined") {
        return invalidCredentials();
    }

    req.token = authModel.getToken(userId,key);

    if(!req.token) {return invalidCredentials();}

    next();

    function invalidCredentials() {
        //Fail with status
        res.status(401)
           .json({message:"Invalid User and Key"}); 
    }
}

Returning `200 OK` for every request masks issues.

Avoid the common pitfalls

Impress your consumers

function verifyUserKey(req, res, next) {
    var userId = req.query.userId,
        key = req.query.key;

    if (typeof userId === "undefined" || typeof key === "undefined") {
        return invalidCredentials();
    }

    req.token = authModel.getToken(userId,key);

    if(!req.token) {return invalidCredentials();}

    next();

    function invalidCredentials() {
        //Fail with status, message, and a code
        res.status(401)
           .json({
                message:"Invalid User and Key"
               ,code:"401"
            }); 
    }
}

Impress your consumers

Some consumers actually won't have access to the underlying response status code
while this is not required, it can make integrating with your API easier.

Flash was a good example of this, the browsers would catch failed requests and not allow the runtime access to the underlying error.

Be remarkable

Operate under the principle of least surprise

 Developers that use your API are almost always on a time crunch. Respect their time.

Make learning your API a no brainer by providing working examples, good documentation and consistent assumptions.

Tools for success

credit: http://www.jaas.co && @jasper9

Postman

swagger.io

Tools for success

Get started

Strive to produce mature API's

Thank you!

Twitter:     @brainchildpro

 

Denver Devs Slack:    james.the.nodester

deck

By James Gibson