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 parametersrequest.query
: query string parametersrequest.route
: current route as a stringrequest.cookies
: cookies, requires cookieParserrequest.signedCookies
: signed cookies, requirescookie-parser
request.body
: body/payload, requiresbody-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 keyrequest.accepts(type)
: checks if the type is acceptedrequest.acceptsLanguage(language)
: checks languagerequest.acceptsCharset(charset)
: checks charsetrequest.is(type)
: checks the typerequest.ip
: IP addressrequest.ips
: IP addresses (with trust-proxy on)request.path
: URL pathrequest.host
: host without port numberrequest.fresh
: checks freshnessrequest.stale
: checks stalenessrequest.xhr
: true for AJAX-y requestsrequest.protocol
: returns HTTP protocolrequest.secure
: checks if protocol ishttps
request.subdomains
: array of subdomainsrequest.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 requestresponse.send(data)
: send responseresponse.json(data):
send JSON and force proper headersresponse.sendfile(path, options, callback)
: send a fileresponse.render(templateName, locals, callback)
: render a templateresponse.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()
1. Microsoft: DEV283x----Introduction to NodeJS
No comments:
Post a Comment