---
outline: deep
---
# Express
As of Feathers v5, [Koa](./koa.md) is the recommended framework integration since it is more modern, faster and easier to use. When chosen explicitly, you should be already familiar [Express](http://expressjs.com/en/guide/routing.html).## express(app) `express(app) -> app` is a function that turns a [Feathers application](./application.md) into a fully Express (4+) compatible application that additionally to Feathers functionality also lets you use the [Express API](http://expressjs.com/en/4x/api.html). ```ts import { feathers } from '@feathersjs/feathers' import express from '@feathersjs/express' const app = express(feathers()) ``` Note that `@feathersjs/express` also exposes the Express [built-in middleware](#built-ins) ## express(app, expressApp) `express(app, expressApp) -> app` allows to extend an existing Express application with the Feathers application `app`. ## express() If no Feathers application is passed, `express() -> app` returns a plain Express application just like a normal call to Express would. ## app.use(path, service|mw|\[mw\]) `app.use(path, service|mw|[mw]) -> app` registers either a [service object](./services.md), an [Express middleware](http://expressjs.com/en/guide/writing-middleware.html) or an array of [Express middleware](http://expressjs.com/en/guide/writing-middleware.html) on the given path. If [a service object](./services.md) is passed it will use Feathers registration mechanism, for a middleware function Express. ```ts // Register a service app.use('todos', { async get(id) { return { id } } }) // Register an Express middleware app.use('/test', (req, res) => { res.json({ message: 'Hello world from Express middleware' }) }) // Register multiple Express middleware functions app.use( '/test', (req, res, next) => { res.data = 'Step 1 worked' next() }, (req, res) => { res.json({ message: `Hello world from Express middleware ${res.data}` }) } ) ``` ## app.listen(port) `app.listen(port) -> Promise
The `json` and `urlencoded` body parser and [params middleware](#params) has to be registered **before** any service.### app.configure(rest(formatter)) The default REST response formatter is a middleware that formats the data retrieved by the service as JSON. If you would like to configure your own `formatter` middleware pass a `formatter(req, res)` function. This middleware will have access to `res.data` which is the data returned by the service. [res.format](http://expressjs.com/en/4x/api.html#res.format) can be used for content negotiation. ```ts import { feathers } from '@feathersjs/feathers' import express, { json, urlencoded, rest } from '@feathersjs/express' const app = express(feathers()) // Turn on JSON parser for REST services app.use(json()) // Turn on URL-encoded parser for REST services app.use(urlencoded({ extended: true })) // Set up REST transport app.configure( rest(function (req, res) { // Format the message as text/plain res.format({ 'text/plain': function () { res.end(`The Message is: "${res.data.text}"`) } }) }) ) ``` ## Custom service middleware Custom Express middleware that only should run before or after a specific service can be passed to `app.use` in the order it should run: ```ts const todoService = { async get(id: Id) { return { id, description: `You have to do ${id}!` } } } app.use('todos', logRequest, todoService, updateData) ```
Custom middleware will only run for REST requests and not when used with other transports (like Socket.io). If possible try to avoid custom middleware and use [hooks](hooks.md) or customized services instead which will work for all transports.Middleware that runs after the service has the service call information available as - `res.data` - The data that will be sent - `res.hook` - The [hook](./hooks.md) context of the service method call For example `updateData` could look like this: ```js function updateData(req, res, next) { res.data.updateData = true next() } ``` If you run `res.send` in a custom middleware after the service and don't call `next`, other middleware (like the REST formatter) will be skipped. This can be used to e.g. render different views for certain service method calls, for example to export a file as CSV: ```ts import json2csv from 'json2csv' const fields = ['done', 'description'] app.use('todos', todoService, function (req, res) { const result = res.data const data = result.data // will be either `result` as an array or `data` if it is paginated const csv = json2csv({ data, fields }) res.type('csv') res.end(csv) }) ``` ## params All Express middleware will have access to the `req.feathers` object to set properties on the service method `params`: ```ts import { feathers } from '@feathersjs/feathers' import type { Id, Params } from '@feathersjs/feathers' import express, { json, urlencoded, rest } from '@feathersjs/express' const app = express(feathers()) app.use(json()) app.use(urlencoded({ extended: true })) app.use(function (req, res, next) { req.feathers.fromMiddleware = 'Hello world' next() }) app.configure(rest()) app.use('todos', { async get(id: Id, params: Params) { console.log(params.provider) // -> 'rest' console.log(params.fromMiddleware) // -> 'Hello world' return { id, params, description: `You have to do ${id}!` } } }) app.listen(3030) ``` Avoid setting `req.feathers = something` directly since it may already contain information that other Feathers plugins rely on. Adding individual properties or using `{ ...req.feathers, something }` is the more reliable option.
Since the order of Express middleware matters, any middleware that sets service parameters has to be registered **before** `app.configure(rest())` or as a [custom service middleware](#custom-service-middleware)
Although it may be convenient to set `req.feathers.req = req` to have access to the request object in the service, we recommend keeping your services as provider independent as possible. There usually is a way to pre-process your data in a middleware so that the service does not need to know about the HTTP request or response.### params.query `params.query` will contain the URL query parameters sent from the client. For the REST transport the query string is parsed using the [qs](https://github.com/ljharb/qs) module. For some query string examples see the [database querying](./databases/querying.md) chapter.
Only `params.query` is passed between the server and the client, other parts of `params` are not. This is for security reasons so that a client can't set things like `params.user` or the database options. You can always map from `params.query` to other `params` properties in a [hook](./hooks.md).For example: ``` GET /messages?read=true&$sort[createdAt]=-1 ``` Will set `params.query` to ```json { "read": "true", "$sort": { "createdAt": "-1" } } ```
Note that the URL is a string so type conversion may be necessary. This is usually done with [query schemas and resolvers](./schema/index.md).
If an array in your request consists of more than 20 items, the [qs](https://www.npmjs.com/package/qs) parser implicitly [converts](https://github.com/ljharb/qs#parsing-arrays) it to an object with indices as keys. To extend this limit, you can set a custom query parser: `app.set('query parser', str => qs.parse(str, {arrayLimit: 1000}))`### params.provider For any [service method call](./services.md) made through REST `params.provider` will be set to `rest`. In a [hook](./hooks.md) this can for example be used to prevent external users from making a service method call: ```ts import { HookContext } from 'declarations' app.service('users').hooks({ before: { remove: [ async (context: HookContext) => { // check for if(context.params.provider) to prevent any external call if (context.params.provider === 'rest') { throw new Error('You can not delete a user via REST') } } ] } }) ``` ### params.headers `params.headers` will contain the original service request headers. ### params.route Express route placeholders in a service URL will be added to the services `params.route`. See the [FAQ entry on nested routes](../help/faq.md#how-do-i-do-nested-or-custom-routes) for more details on when and when not to use nested routes. ```ts import { feathers } from '@feathersjs/feathers' import express, { rest } from '@feathersjs/express' const app = express(feathers()) app.configure(rest()) app.use(function (req, res, next) { req.feathers.fromMiddleware = 'Hello world' next() }) app.use('users/:userId/messages', { async get(id, params) { console.log(params.query) // -> ?query console.log(params.provider) // -> 'rest' console.log(params.fromMiddleware) // -> 'Hello world' console.log(params.route.userId) // will be `1` for GET /users/1/messages return { id, params, read: false, text: `Feathers is great!`, createdAt: new Date().getTime() } } }) app.listen(3030) ``` ## Middleware `@feathersjs/express` comes with the following middleware ### notFound(options) `notFound()` returns middleware that returns a `NotFound` (404) [Feathers error](./errors.md). It should be used as the last middleware **before** the error handler. The following options are available: - `verbose`: Set to `true` if the URL should be included in the error message (default: `false`) ```ts import { notFound, errorHandler } from '@feathersjs/express' // Return errors that include the URL app.use(notFound({ verbose: true })) app.use(errorHandler()) ``` ### errorHandler() `errorHandler` is an [Express error handler](https://expressjs.com/en/guide/error-handling.html) middleware that formats any error response to a REST call as JSON (or HTML if e.g. someone hits our API directly in the browser) and sets the appropriate error code.
You can still use any other Express compatible [error middleware](http://expressjs.com/en/guide/error-handling.html) with Feathers.
Just like in Express, the error handler has to be registered _after_ all middleware and services.#### app.use(errorHandler()) Set up the error handler with the default configuration. ```ts import { feathers } from '@feathersjs/feathers' import express from '@feathersjs/express' const app = express(feathers()) // before starting the app app.use(express.errorHandler()) ``` #### app.use(errorHandler(options)) ```ts import { feathers } from '@feathersjs/feathers' import express from '@feathersjs/express' const app = express(feathers()) // Just like Express your error middleware needs to be // set up last in your middleware chain. app.use( express.errorHandler({ html: function (error, req, res, next) { // render your error view with the error object res.render('error', error) } }) ) app.use( errorHandler({ html: { 404: 'path/to/notFound.html', 500: 'there/will/be/robots.html' } }) ) ```
If you want to have the response in json format be sure to set the `Accept` header in your request to `application/json` otherwise the default error handler will return HTML.The following options can be passed when creating a new error handler: - `html` (Function|Object) [optional] - A custom formatter function or an object that contains the path to your custom html error pages. Can also be set to `false` to disable html error pages altogether so that only JSON is returned. - `logger` (Function|false) (default: `console`) - Set a logger object to log the error (it will be logger with `logger.error(error)` ### authenticate() `express.authenticate(...strategies)` allows to protect an Express middleware with an [authentication service](./authentication/service.md) that has [strategies](./authentication/strategy.md) registered that can parse HTTP headers. It will set the authentication information on the `req` object (e.g. `req.user`). The following example protects the `/hello` endpoint with the JWT strategy (so the `Authorization: Bearer
When using HTTPS URLs are safely encrypted but when using this method you have to make sure that access tokens are not logged through any of your logging mechanisms.### parseAuthentication The `parseAuthentication` middleware is registered automatically and will use the strategies of the default [authentication service](./authentication/service.md) to parse headers for authentication information. If you want to additionally parse authentication with a different authentication service this middleware can be registered again with that service configured. ```ts import { parseAuthentication } from '@feathersjs/express' app.use( parseAuthentication({ service: 'api/v1/authentication', strategies: ['jwt', 'local'] }) ) ``` ### cors A reference to the [cors](https://github.com/expressjs/cors) module. ### compression A reference to the [compression](https://github.com/expressjs/compression) module. ### Built ins Note that `@feathersjs/express` also exposes the standard [Express middleware](http://expressjs.com/en/4x/api.html#express): - `json` - A JSON body parser - `urlencoded` - A URL encoded form body parser - `serveStatic` - To statically host files in a folder - `Router` - Creates an Express router object