2 - Express WebApp

We will now convert our app into a webapp.

Express

npm install express method-override morgan body-parser cors -—save

Now change index.js replacing the code with the following

import app from './src/server'

const isProduction = process.env.NODE_ENV === 'production'
const port = isProduction ? process.env.PORT : 3001

app.listen(port, () => {
  /* eslint-disable no-console */
  console.log(`Server running on port ${port}`)
})

Lets start to organize the code, so create a src folder and the server.js file within it

mkdir src
vi src/server.js

Including the following content

import express from 'express'

const app = express()

app.get('/', (req, res) => {
  res.status(200).send('hello')
})

export default app

Now we have a simple webserver listening on port 3001 (test environment). So let start it

npm start

And now you can check it either by a UI client like Postman or with a curl command

curl http://localhost:3001/
> hello

Testing the web server (supertest)

That's a start. Now lets setup the infrastructure to start testing the webservice right away.

We will use the supertest which is nice library to test http requests with expectations for the response.

So lets install the dependency

npm install --save-dev supertest

And now we will start also organizing the code. Lets create a folder for this new kind of tests and an initial test.

mkdir test/integration
vi test/integration/api_spec.js

With the following content

/* eslint-env node, mocha */
import request from 'supertest'

import app from '../../src/server'

describe('API', () => {

  it('requestiong / gives a hello', (done) => {
    request(app)
        .get('/')
        .expect(200, 'hello', done)
  })

})

Lets also remove the old test

rm test/hello_spec.js

Now run the tests

npm test

Logger

Now our server is a sad one. Every time it receives a request it doesn't log anything so it is difficult to develop/debug.

Lets add a logger library

npm install --save morgan

Then edit server.js file and add the following lines (only the ones with comments at the end

import express from 'express'
import morgan from 'morgan'        // ADD

const app = express()

app.use(morgan('dev'))             // ADD

// ...

Now start the server again and perform a request. You should see something like

[nodemon] 1.11.0
[nodemon] to restart at any time, enter `rs`
[nodemon] watching: *.*
[nodemon] starting `babel-node index`
Server running on port 3001

GET / 200 3.107 ms - 5

Notice the last line !

Setting-up Express

Now in order to successfully process JSON as input and forms data sent to the server we need to configure express. And we will also configure some other misc tasks by using middlewares

npm install --save body-parser compression method-override

As we are going to configure a couple of things into our app it is better to take away that code to keep server.js simple, so go ahead and create a folder and a new file for this configurations

mkdir src/config
vi src/config/express.js

And add the following content

import methodOverride from 'method-override'
import bodyParser from 'body-parser'
import morgan from 'morgan'
import compression from 'compression'

export default function(app) {
  app.use(methodOverride())

  app.use(bodyParser.urlencoded({ extended: 'true' }))            // parse application/x-www-form-urlencoded
  app.use(bodyParser.json())                                     // parse application/json
  app.use(bodyParser.json({ type: 'application/vnd.api+json' })) // parse application/vnd.api+json as json

  app.use(morgan('dev'))
  app.use(compression())
}

We will now update server.js to include this new file and to remove the morgan configuration from there. It should look like this

import express from 'express'

const app = express()

import config from './config/express'      // ADDED
config(app)                                // ADDED


app.get('/', (req, res) => {
  res.status(200).send('hello')
})


export default app

So lets try it out with a new end-point.

Edit server.js and add the following

app.post('/', (req, res) => {
  const message = `hello ${req.body.to}!`
  res.json({ status: 'ok', message: message })
})

Notice that we are using the body attribute from the request. This is possible because of our previous configuration (body-parsers). In this case we are expecting a body with a JSON object like

{
   "to" : "someone"
}

We can also write directly a json response with .json() method.

So go ahead an try it with curl (or postman)

 curl -X POST http://localhost:3001/ --data '{ "to" : "pepito" }'
 > {"status":"ok","message":"hello undefined!"}

But now lets add a new test case for this. Edit test/integration/api_spec.js and add

  it('POST / gives a hello including the to', (done) => {
    request(app)
        .post('/')
        .send({ to: 'someone' })
        .expect('Content-Type', /json/)
        .expect(200, {status: "ok", message: "hello someone!"}, done)
  })

Now run the tests again.

results matching ""

    No results matching ""