For a while now, most of my new development has been working on interaction heavy client-side apps. So, with this, I've been wanting a better way of throwing up APIs fast.
I've learned enough Rails to cut my teeth in. But, I'm still not entirely comfortable putting a new app on it. And, when it comes to PHP with Laravel or Symfony, I tend to over architect things.
What I really have been craving was a HEAVILY opinionated set of tools to make APIs. The list is pretty short but here's what my ideal toolset would contain:
- Easy 1-2 line route declarations
- API formatting (for things like HAL or JSON API)
- Clear DSLs for attribute binding
- File and project organization
So after some thought, I messaged another JS instructor the following code:
function(req, res) {
return req.store.resourceCollection('events', {queryBy: ['category'], orderBy: 'startDate'});
}
"Wouldn't it be nice?" I thought.
Then this last week, I looked back at this code and one of my Express apps and thought I should give it a shot.
But, before I started, I wanted to set some ground rules:
- Make future room for abstraction in 2 main places
- ORM layer
- Serialization/Normalization
- Don't solve every problem (we can always just write usual express routes later)
After a few hours I now have a decent start. There's still room to go before making a true NPM package from what works, but here's what a set of routes for a single resource looks like:
var express = require('express');
var router = express.Router();
router.get('/', function(req, res) {
return req.store.recordCollection('Book', {
include: ['author'],
queryBy: ['year'],
orderBy: 'year',
});
});
router.get('/:id', function(req, res) {
return req.store.recordItemById('Book', req.params.id);
});
router.post('/', function(req, res) {
return req.store.createRecord('Book', {
include: ['author'],
beforeSave: (book, save) => {
book.author = '563ed344bd48dfad25a9dbd2';
save();
},
});
});
module.exports = router;
I think it's pretty clean so far. But let me know what you think.