//

Friday, June 21, 2019

Implement REST API routing

Implementing REST API Routing

Servers must have routes, otherwise they are not useful at all. As a very basic example, consider this Express route which serves Hello World string to requests made to / (root address):
app.get('/', (req, res) => {
  res.send('Hello World')
})
You can notice that app.get() is referring to the GET HTTP method. That's what browsers will use navigate to a URL in a browser.
The first argument is a URL string. It could be a regular expression as well. The second argument is a request handler with request and response objects.
If you have two routes in app.js:
const {homePage, getUsers} = require('./routes')

app.get('/', homePage)
app.get('/users', getUsers)
The first one basically takes care of all the GET requests to the home page (/), such as http://localhost:3000/ and triggers the homPage method. The second takes care of requests to /users, such as http://localhost:3000/users and triggers the getUsers method.
Both of the routes process URLs in a case-insensitive manner and in the same way with trailing slashes.

Handling Various HTTP requests

Similarly, Express allows you to define other HTTP methods via its app.{method_name}() API:

  • app.post(): POST requests are used for creation of new entities
  • app.put(): PUT requests are used for complete replacements or partial updates
  • app.patch(): PATCH requests are used for partial updates
  • app.delete(): DELETE requests are used for removal of existing entities
  • app.head(): HEAD requests are idential to GET requests but without the body
  • app.options(): OPTIONS requests are used to identify allowed methods
Additionaly, the method app.all() will define the request handler for any HTTP method. app.all('*', fn) is used mostly as a final catch to show 404: Not Found. If you put this first, then nothing will be executed after this route.
Take a look at this example in which a profile object is read and changed via four routes with GET, POST, PUT and DELETE methods:
const express = require('express') 
const app = express() 

const profile = {
  username: 'azat',
  email: '[reducted]',
  url: 'http://azat.co'
}
app.get('/profile', (req, res)=>{
  res.send(profile)
})
app.post('/profile', (req, res) => {
  profile = req.body
  res.sendStatus(201)
})
app.put('/profile', (req, res)=>{
  Object.assign(profile, req.body)
  res.sendStatus(204)
})
app.delete('/profile', (req, res)=>{
  profile ={}
  res.sendStatus(204)
})

app.listen(3000)
To test this server, simply run it with node server.js and then use your favorite client such as CURL or Postman to submit HTTP requests.
The result is that with minimal code you can have all CRUD functionality via a RESTful HTTP interface.

Express Request

The Express request object has more properties than the core http request from which it extends. These properties simplify development and provide extra functionality.
  • request.params: URL parameters
  • request.query: query string parameters
  • request.route: current route as a string
  • request.cookies: cookies, requires cookieParser
  • request.signedCookies: signed cookies, requires cookie-parser
  • request.body: body/payload, requires body-parser
  • request.headers: headers

Request Header Shortcuts


There are special properties and methods which provide access to HTTP request header information. These shortcuts are known as sugarcoating because everything they do can be done with request.headers.
  • request.get(headerKey): value for the header key
  • request.accepts(type): checks if the type is accepted
  • request.acceptsLanguage(language): checks language
  • request.acceptsCharset(charset): checks charset
  • request.is(type): checks the type
  • request.ip: IP address
  • request.ips: IP addresses (with trust-proxy on)
  • request.path: URL path
  • request.host: host without port number
  • request.fresh: checks freshness
  • request.stale: checks staleness
  • request.xhr: true for AJAX-y requests
  • request.protocol: returns HTTP protocol
  • request.secure: checks if protocol is https
  • request.subdomains: array of subdomains
  • request.originalUrl: original URL

HTTP Responses

The response object is also accessible via routing handlers in Express because it is the second argument in the handler's callback:
app.get('/users/:id', function (request, response) {
  // 'response' is the enhanced response from http
})
The response object is used to send the response and to modify an HTTP response before sending it out.

Express Response Method

The Express response object has additional methods to the core http's statusCode()writeHead()end() and write().
  • response.redirect(url): redirect request
  • response.send(data): send response
  • response.json(data): send JSON and force proper headers
  • response.sendfile(path, options, callback): send a file
  • response.render(templateName, locals, callback): render a template
  • response.locals: pass data to template

HTTP Status Codes

To specify a status code, use the response object's status function:
app.get('/user/:id', function (request, response) {
  // Logic to check for user
  if (!exists) {
    response.status(404)
  } else if (authorized) {
    response.status(200)
  } else {
    response.status(401)
  }
  // ...
})

HTTP Status Codes List

  • 2XX: for successfully processed requests
  • 3XX: for redirections or cache information
  • 4XX: for client-side errors
  • 5XX: for server-side errors
Note: for 3xx status codes, the client must take additional action following the completion of the current request

Sending a Response

Use the response object's send function to send the client a response:
app.get('...', function (request, response) {
  response.send('Hello World!')
})

Sending a Response

The content-type is determined given the type of argument passed:
response.send('Hello World!')       // Content-type: text/plain
response.send([ 5, 7, 9 ])          // Content-type: application/json
response.send({ name: 'John Doe' }) // Content-type: application/json
Sending an empty response 
The content-type can also be hardcoded:
response.set('Content-Type', 'text/plain')
response.send('Just regular text, no html expected!')

Some status codes like 204 do not support (according to the W3C specs) a body. Express allows you to send an empty body:
response.status(204).end()
Other status codes can be also used with an empty body:
response.status(404).end()

Ref:
1. Microsoft: DEV283x----Introduction to NodeJS

No comments:

Post a Comment

Effective Branching Strategies in Development Teams

Effective Branching Strategies in Development Teams Effective Branching Strategies in Developme...