Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Changes 01-02 – Express middlewares and request handlers #2

Open
wants to merge 13 commits into
base: 01-setup
from
Open
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file or symbol
Failed to load files and symbols.

Always

Just for now

@@ -0,0 +1,6 @@
## 2 – Express Middlewares and Request Handlers

Now the server application gets its first REST API endpoint implemented. So start the server using `npm start` and visit:

1. `http://localhost:8000/api/cat/1` – It responds with a 404
2. `http://localhost:8000/api/cat/123` – It responds with a 200 and very little information about a cat

Some generated files are not rendered by default. Learn more.

Oops, something went wrong.
@@ -13,10 +13,15 @@
"prettier:write": "prettier --write service/**/*.{ts,tsx,js,jsx}"
},
"dependencies": {
"express": "^4.16.2"
"express": "^4.16.2",
"compression": "1.7.2",
"cookie-parser": "1.4.3",
"http-status-codes": "1.3.0"
},
"devDependencies": {
"@types/express": "4.11.1",
"@types/compression": "0.0.35",
"@types/cookie-parser": "1.4.1",
"typescript": "3.1.1",
"ts-node": "6.1.1",
"prettier": "^1.9.2"
@@ -1,12 +1,13 @@
import { ExpressServer } from './ExpressServer'
import { CatEndpoints } from './cats/CatEndpoints'

/**
* Wrapper around the Node process, ExpressServer abstraction and complex dependencies such as services that ExpressServer needs.
* When not using Dependency Injection, can be used as place for wiring together services which are dependencies of ExpressServer.
*/
export class Application {
public static async createApplication() {
const expressServer = new ExpressServer()
const expressServer = new ExpressServer(new CatEndpoints())
await expressServer.setup(8000)
Application.handleExit(expressServer)

@@ -1,6 +1,12 @@
import * as express from 'express'
import { Express } from 'express'
import { Server } from 'http'
import * as compress from 'compression'
import * as bodyParser from 'body-parser'
import * as cookieParser from 'cookie-parser'

import { noCache } from './NoCacheMiddleware'
import { CatEndpoints } from './cats/CatEndpoints'

/**
* Abstraction around the raw Express.js server and Nodes' HTTP server.
@@ -11,8 +17,14 @@ export class ExpressServer {
private server?: Express
private httpServer?: Server

constructor(private catEndpoints: CatEndpoints) {
}

public async setup(port: number) {
const server = express()
this.setupStandardMiddlewares(server)
this.configureApiEndpoints(server)

this.httpServer = this.listen(server, port)
this.server = server
return this.server
@@ -25,4 +37,14 @@ export class ExpressServer {
public kill() {
if (this.httpServer) this.httpServer.close()
}

private setupStandardMiddlewares(server: Express) {
server.use(bodyParser.json())
server.use(cookieParser())
server.use(compress())
}

private configureApiEndpoints(server: Express) {
server.get('/api/cat/:catId', noCache, this.catEndpoints.getCatDetails)
}
}
@@ -0,0 +1,8 @@
import { Request, Response, NextFunction } from 'express'

export function noCache(_: Request, res: Response, next: NextFunction) {
res.setHeader('Expires', '0')
res.setHeader('Pragma', 'no-cache')
res.setHeader('Cache-Control', 'no-cache, no-store, must-revalidate')
next()
}
@@ -0,0 +1,21 @@
import { NextFunction, Request, Response } from 'express'
import * as HttpStatus from 'http-status-codes'

export class CatEndpoints {
public getCatDetails = async (req: Request, res: Response, next: NextFunction) => {
try {
// usually we will contact some service here and do some logic
const catId = req.params.catId

if (catId >= 90) {
res.json({ catId, name: 'Some lovely Kitty' })
} else {
res.sendStatus(HttpStatus.NOT_FOUND)
}
} catch (err) {
// something could fail unexpectedly...
// at some point the middleware chain should handle errors
next(err)
}
}
}
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.