Koa
npm install @feathersjs/koa --save
The @feathersjs/koa
module contains the KoaJS framework integrations for Feathers. It will turn the Feathers app into a fully compatible KoaJS application.
koa(app)
koa(app) -> app
is a function that turns a Feathers application into a fully KoaJS compatible application that additionally to Feathers functionality also lets you use the KoaJS API.
import { feathers } from '@feathersjs/feathers'
import { koa, errorHandler, bodyParser, rest } from '@feathersjs/koa'
const app = koa(feathers())
app.use(errorHandler())
app.use(authentication())
app.use(bodyParser())
app.configure(rest())
Also see the additional middleware that @feathersjs/koa
exposes.
koa(app, koaApp)
koa(app, koaApp) -> app
allows to extend an existing Koa application with the Feathers application app
.
koa()
If no Feathers application is passed, koa() -> app
returns a plain Koa application (new Koa()
).
app.use(location|mw[, service])
app.use(location|mw[, service]) -> app
registers either a service object, or a Koa middleware. If a path and service object is passed it will use Feathers registration mechanism, for a middleware function Koa.
app.listen(port)
app.listen(port) -> HttpServer
will first call Koa app.listen and then internally also call the Feathers app.setup(server).
// Listen on port 3030
const server = await app.listen(3030)
app.setup(server)
app.setup(server) -> app
is usually called internally by app.listen
but in the cases described below needs to be called explicitly.
HTTPS
HTTPS requires creating a separate server in which case app.setup(server)
also has to be called explicitly. In a generated application src/index.js
should look like this:
import https from 'https'
import { app } from './app'
const port = app.get('port')
const server = https
.createServer(
{
key: fs.readFileSync('privatekey.pem'),
cert: fs.readFileSync('certificate.pem')
},
app.callback()
)
.listen(443)
// Call app.setup to initialize all services and SocketIO
app.setup(server)
server.on('listening', () => logger.info('Feathers application started'))
params
In a Koa middleware, ctx.feathers
is an object which will be extended as params
in a service method call.
import { rest } from '@feathersjs/koa'
import type { NextFunction } from '@feathersjs/koa'
import type { Id, Params } from '@feathersjs/feathers'
class TodoService {
async get(id: Id, params: Params & { fromMiddleware: string }) {
const { fromMiddleware } = params
return { id, fromMiddleware }
}
}
// Register Koa middleware
app.use(async (ctx: any, next: NextFunction) => {
ctx.feathers = {
...ctx.feathers,
fromMiddleware: 'Hello from Koa middleware'
}
await next()
})
app.configure(rest())
// Register a service
app.use('todos', new TodoService())
Important
Note that app.configure(rest())
has to happen after any custom middleware.
params.query
params.query
will contain the URL query parameters sent from the client parsed using koa-qs.
important
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.
To increase the array limit in query strings, koa-qs
can be reinitalized with the options for the qs module:
// app.ts
import koaQs from 'koa-qs'
// ...
koaQs(app, 'extended', {
arrayLimit: 200
})
params.provider
For any service method call made through REST params.provider
will be set to rest
.
params.route
Route placeholders in a service URL will be added to the services params.route
. See the FAQ entry on nested routes for more details on when and when not to use nested routes.
import { feathers } from '@feathersjs/feathers'
import { koa, errorHandler, bodyParser, rest } from '@feathersjs/koa'
const app = koa(feathers())
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) // will be `{ userId: '1' }` for GET /users/1/messages
return {
id,
params,
read: false,
text: `Feathers is great!`,
createdAt: new Date().getTime()
}
}
})
app.listen(3030)
Service middleware
When registering a service, it is also possible to pass custom Koa middleware that should run before
the specific service method in the koa
service option:
app.use('/todos', new TodoService(), {
koa: {
before: [
async (ctx, next) => {
ctx.feathers // data that will be merged into sevice `params`
// This will run all subsequent middleware and the service call
await next()
// Then we have additional properties available on the context
ctx.hook // the hook context from the method call
ctx.body // the return value
}
]
}
})
Note that the order of middleware will be [...before, serviceMethod]
.
Middleware
rest
import { rest } from '@feathersjs/koa'
app.configure(rest())
Configures the middleware for handling service calls via HTTP. It will also register authentication header parsing. The following (optional) options are available:
formatter
- A middleware that formats the response bodyauthentication
- The authenticationservice
andstrategies
to use for parsing authentication information
errorHandler
import { errorHandler } from '@feathersjs/koa'
app.use(errorHandler())
A middleware that formats errors as a Feathers error and sets the proper status code. Needs to be the first middleware registered in order to catch all other errors.
authenticate
A middleware that allows to authenticate a user (or other authentication entity) using the authentication service setting ctx.feathers.user
. Not necessary for use with services but can be used in custom middleware.
import { authenticate } from '@feathersjs/koa'
// Authenticate other middleware with the JWT strategy
app.use(authenticate('jwt'))
// Authenticate a non default service
app.use(
authenticate({
service: 'api/v1',
strategies: ['jwt']
})
)
parseAuthentication
The parseAuthentication
middleware is registered automatically and will use the strategies of the default authentication service 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.
import { parseAuthentication } from '@feathersjs/koa'
app.use(
parseAuthentication({
service: 'api/v1/authentication',
strategies: ['jwt', 'local']
})
)
bodyParser
A reference to the koa-body module.
cors
A reference to the @koa/cors module.
serveStatic
A reference to the koa-static module.