Building API's Quicker
Website: gibsunas.co
Twitter: @thenodester
Github: james-gibson
Denver Devs Slack: james.the.nodester
Platform Architect & Co-Founder @
Gibsunas Consulting, LLC
So you've run the express generator, now what?
app.use(express.static(path.join(__dirname, 'public')));We won't need static hosting for the API because it will be serving up only JSON
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');Also, remove the view engine
app.use(cookieParser());Our API will use token-based auth so no cookies needed
Don't forget to remove the things mentioned above from your package.json as well!
npm i -S dotenv
// Using PostgreSQL?
npm i -S pg knex
// Using MongoDB?
// Not my problem.These packages might come in handy
npm i --save-dev eslint
npm i --save-dev jest
npm i --save-dev flow
These will come in handy
app.get('/health', (req, res, next) => {
res.status(204);
res.send();
});Health check for future automation
app.use((req, res, next) => {
req.custom = {
// Add objects/functions here that make your life
// easier when you are processing requests.
postgres: ...,
redis: ...,
};
next();
});Install custom services into your request object
var knex = require('knex')({
client: 'postgres',
connection: process.env.DATABASE_URL
// i.e. postgres://user:pass@localhost:5432/dbname
});Instantiate that db connection
app.use((error, req, res, next) => {
let baseResponse = {
status:'50x'
};
let envResponse;
if(process.env.NODE_ENV == 'development') {
envResponse = {
message: error.message
};
} else {
envResponse = {
message: 'Looks like something broke'
};
}
let response = Object.assign(
{},
baseResponse,
envResponse
);
res.json(response);
});app.use((req, res, next) => {
res.removeHeader('Content-Encoding');
res.removeHeader('X-Powered-By');
next();
});Why should we announce that this is an Express server?
app.use(cors());npm i -S corsapp.use((req, res, next) => {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content-Type, Accept");
next();
});||
var passport = require('passport');
var GoogleStrategy =
require('passport-google-oauth').OAuthStrategy;
passport.use(new GoogleStrategy({
consumerKey: GOOGLE_CONSUMER_KEY,
consumerSecret: GOOGLE_CONSUMER_SECRET,
callbackURL: "https://<your url here>/callback"
},
function(token, tokenSecret, profile, done) {
// verify user here
}
));
This seems like overkill...
Please don't mistake me, oAuth is pretty awesome. But it comes with a lot of setup.
var passport = require('passport')
, LocalStrategy = require('passport-local').Strategy;
passport.use(new LocalStrategy(
(username, password, done) => {
// verify the given credentials match what
// you'd expect in your db
}
));We'd still have the user management issue
very simple.
app.use((req, res, next) => {
let expectedToken = process.env.API_AUTH_TOKEN;
let { token } = req.query;
if(expectedToken !== token) {
res.status(401);
res.json({
error: "Unauthorized action"
});
}
next();
});Where API_AUTH_TOKEN:
(run this in your cmd line)
openssl rand -base64 30 #Don't commit this!FROM node:8.4
WORKDIR /usr/src/app
COPY package.json .
COPY . .
RUN yarn
CMD ["npm", "start"]Our problems are not always unique
This is for fun isn't it?
* This is a referral link.
Website: gibsunas.co
Twitter: @thenodester
Github: james-gibson
Denver Devs Slack: james.the.nodester