Diving in API design — part 1

Matei Oprea
4 min readMar 22, 2017

--

Recently I’ve started to design an API and I had to do a lot of research about industry best practices, what technology is better and why should I use it, how to write routes for my API, etc. This is the first from a series of articles that documents my journey into designing and building an API. The focus will be on ORMs, response standards and my recommendations for initial configuration.

Introduction

My main goal was to use a programming language that is pretty easy to learn or it’s already used by a lot of people. Why? Well, if you think it like a business, you should be able to easily recruit people to work on your project. Usually the most used programming languages have a lot of community around them and it’s easier to ask questions.

A project like this can start fast and can easily end up faster than it started if you can’t find someone who can code it.

So… How do I start?

With patience :). I’ve used NodeJS (it’s easy, fast and we can easily scale it horizontally. Also the community is pretty big and you have node package manager). For me, the main concern was how to organise routes and how to secure the API. krakenjs can do that with ease and initialising a project is piece of cake (check their website).

yo kraken

will do the job easily. Kraken helped me a lot with not having to create and organise everything into the project. Also it’s advertised as a layer built on top of express that gives you structure and convention. Exactly what you need for a healthy project.

What was the most important stuff for me when I started this:

I need an ORM. I found one, I didn’t liked it and I’ve started looking for another one. Sequelize wasn’t a good fit either because I saw a lot of complaints that it can overwrite your DB tables if you’re not careful with it. Nobody wants that.

My needs were pretty simple: I need a Javascript ORM that I can easily understand, I don’t have to write detailed models for and it’s pretty simple to integrate with what we currently have (MySQL). Bookshelf was the answer.

Bookshelf is a Javascript ORM which is built on top Knex. It features promise based / traditional callbacks, relations (one-to-one, one-to-many, many-to-many), etc.

I’m a lazy guy. Being lazy is usually (not???) a good thing. Let’s see the difference between defining a model with Sequelize vs defining one with Bookshelf.

We have a table named Users with the following columns: id, name, email, address.

Sequelize way:

let Users = sequelize.define('users', {
id: Sequelize.INTEGER,
name: Sequelize.TEXT,
email: Sequelize.STRING,
address: Sequelize.TEXT
});

Imagine doing this for every table in MySQL… and going back to the model every time you add a new column.

Bookshelf way:

let Users = bookshelf.Model.extend({
tableName: 'users',
});

That’s it. Than you can do whatever you want with the model. Define your own custom functions, relations between tables. You name it. From my point of view, everything needs to be kept simple.

One more thing: the fact that Bookshelf is built on top of Knex helps a lot. You can easily use QueryBuilder to define whatever you think it’s missing from your query (limit, offset, etc). Example:

user.query((qb) => { qb.limit(10).offset(5) }).fetchAll().then...

Will fetch 10 users starting from the 5th one.

Responses

Although there’s no standard for API responses I’ve decided to follow Google JSON Style guide. Following a standard (even if you define one by yourself) only does good for your application. After you’ve decided what do you want to use, stick to it.

Basically, the guide says that you should respond with a data object whenever the query is a successful one or with error object when something bad happened. Example:

GET /users/1

If the user with id = 1 exists we’ll respond with

{
data: [
{
id: 1
name: Matei Oprea
email: dummy@email.com
}
]
}

Additional fields can be there. If we encounter any error, the response can be the following:

{
error: {
message: Something bad happened
type: 1
}
}

P.s.: Beware of SQL Injection and always sanitize fields.

Conclusion

Based on my research that took 1–2 weeks you have plenty of options that you can use. Use that one that will fits your needs, gives you the best flow when writing code. Keeping it simple will help you in the future when you’ll have a big app that can be maintained with ease.

Also, Bookshelf rocks.

Image credits: https://www.xda-developers.com/tag/api/

--

--