Documentation Index Fetch the complete documentation index at: https://mintlify.com/feathersjs/feathers/llms.txt
Use this file to discover all available pages before exploring further.
The @feathersjs/koa package provides integration between Feathers and Koa, bringing async/await middleware patterns and lightweight HTTP handling to your Feathers services.
Installation
npm install @feathersjs/koa koa
Basic Setup
Create the Koa application
The Koa integration wraps a Feathers application with Koa functionality: import { feathers } from '@feathersjs/feathers'
import { koa } from '@feathersjs/koa'
const app = koa ( feathers ())
Add body parsing middleware
Enable request body parsing for POST/PUT/PATCH requests: import { bodyParser } from '@feathersjs/koa'
app . use ( bodyParser ())
Configure REST transport
Enable the REST transport to expose services via HTTP: import { rest } from '@feathersjs/koa'
app . configure ( rest ())
Register services
Services are automatically exposed as REST endpoints: app . use ( '/users' , {
async find () {
return [{ id: 1 , name: 'Alice' }]
},
async get ( id ) {
return { id , name: 'Alice' }
}
})
Add error handling
Use the error handler middleware to catch and format errors: import { errorHandler } from '@feathersjs/koa'
app . use ( errorHandler ())
Start the server
The listen method automatically calls setup() on all services: await app . listen ( 3030 )
console . log ( 'Feathers app started on http://localhost:3030' )
Complete Example
import { feathers } from '@feathersjs/feathers'
import { koa , rest , bodyParser , errorHandler , cors } from '@feathersjs/koa'
const app = koa ( feathers ())
// Middleware must be added before REST configuration
app . use ( errorHandler ())
app . use ( cors ())
app . use ( bodyParser ())
// Configure REST transport
app . configure ( rest ())
// Register services
app . use ( '/messages' , {
async find () {
return [
{ id: 1 , text: 'Hello world' },
{ id: 2 , text: 'How are you?' }
]
},
async create ( data ) {
return { id: 3 , ... data }
}
})
// Custom Koa middleware
app . use ( async ( ctx , next ) => {
if ( ctx . path === '/health' ) {
ctx . body = { status: 'ok' }
} else {
await next ()
}
})
// Start server
const server = await app . listen ( 3030 )
console . log ( 'Server ready on http://localhost:3030' )
Service Middleware
Koa middleware can be added before and after service calls using the koa option:
import { Middleware } from '@feathersjs/koa'
const logRequest : Middleware = async ( ctx , next ) => {
console . log ( ` ${ ctx . method } ${ ctx . path } ` )
await next ()
}
const addTimestamp : Middleware = async ( ctx , next ) => {
await next ()
ctx . body = { ... ctx . body , timestamp: new Date () }
}
app . use ( '/todos' , todoService , {
koa: {
before: [ logRequest ],
after: [ addTimestamp ]
},
methods: [ 'find' , 'get' , 'create' ]
})
Middleware Patterns
Before Middleware
After Middleware
Combined
Middleware in the before array runs before the service method: const validateRequest : Middleware = async ( ctx , next ) => {
if ( ! ctx . request . headers . authorization ) {
ctx . throw ( 401 , 'Unauthorized' )
}
await next ()
}
app . use ( '/protected' , service , {
koa: {
before: [ validateRequest ]
}
})
Middleware in the after array runs after the service method and can modify ctx.body: const formatResponse : Middleware = async ( ctx , next ) => {
await next ()
ctx . body = {
status: 'success' ,
data: ctx . body ,
timestamp: new Date ()
}
}
app . use ( '/api/users' , userService , {
koa: {
after: [ formatResponse ]
}
})
Use both before and after middleware together: app . use ( '/todos' , todoService , {
koa: {
before: [
async ( ctx , next ) => {
ctx . state . startTime = Date . now ()
await next ()
}
],
after: [
async ( ctx , next ) => {
await next ()
const duration = Date . now () - ctx . state . startTime
ctx . set ( 'X-Response-Time' , ` ${ duration } ms` )
}
]
}
})
Context and Feathers Params
Koa’s ctx.feathers object contains Feathers-specific parameters:
app . use ( async ( ctx , next ) => {
// Access Feathers params
console . log ( ctx . feathers . provider ) // 'rest'
console . log ( ctx . feathers . headers ) // Request headers
// Add custom params that services will receive
ctx . feathers . customData = { userId: 123 }
await next ()
})
app . use ( '/items' , {
async find ( params ) {
// params includes ctx.feathers properties
console . log ( params . customData ) // { userId: 123 }
console . log ( params . provider ) // 'rest'
return []
}
})
Authentication
Integrate Feathers authentication with Koa middleware:
import { authenticate } from '@feathersjs/koa'
// Protect routes with authentication
app . use ( '/admin' , authenticate ( 'jwt' ), adminService )
// Authentication middleware
const requireAuth : Middleware = authenticate ( 'jwt' )
app . use ( async ( ctx , next ) => {
if ( ctx . path . startsWith ( '/api/' )) {
await requireAuth ( ctx , next )
} else {
await next ()
}
})
Authentication Configuration
import { rest , parseAuthentication } from '@feathersjs/koa'
// Configure REST with automatic authentication parsing
app . configure ( rest ({
authentication: {
service: 'authentication' ,
strategies: [ 'jwt' , 'local' ]
}
}))
// Or add authentication parsing globally
app . use ( parseAuthentication ({
service: 'authentication' ,
strategies: [ 'jwt' ]
}))
Error Handling
Koa error handling is done through middleware:
Default Handler
Custom Handler
With Logging
import { errorHandler } from '@feathersjs/koa'
// Use default error handler (must be first middleware)
app . use ( errorHandler ())
app . use ( bodyParser ())
app . configure ( rest ())
Static Files
Serve static files using Koa’s static middleware:
import { serveStatic } from '@feathersjs/koa'
import path from 'path'
// Serve static files from public directory
app . use ( serveStatic ( path . join ( __dirname , 'public' )))
// Serve with options
app . use ( serveStatic ( 'assets' , {
maxage: 86400000 , // 1 day
hidden: false
}))
Customize how service results are sent as HTTP responses:
import { rest , Middleware } from '@feathersjs/koa'
const customFormatter : Middleware = async ( ctx , next ) => {
await next ()
// Wrap all responses
if ( ctx . body ) {
ctx . body = {
success: true ,
result: ctx . body ,
timestamp: Date . now ()
}
}
}
app . configure ( rest ({ formatter: customFormatter }))
Using Existing Koa App
Integrate Feathers into an existing Koa application:
import Koa from 'koa'
import { koa as feathersKoa } from '@feathersjs/koa'
import { feathers } from '@feathersjs/feathers'
// Existing Koa app
const koaApp = new Koa ()
koaApp . use ( async ( ctx , next ) => {
if ( ctx . path === '/health' ) {
ctx . body = { status: 'ok' }
} else {
await next ()
}
})
// Add Feathers to it
const app = feathersKoa ( feathers (), koaApp )
app . configure ( rest ())
app . use ( '/api/users' , userService )
await app . listen ( 3030 )
Pure Koa Middleware
You can mix Feathers services with pure Koa middleware:
import { koa , rest , bodyParser } from '@feathersjs/koa'
import Router from '@koa/router'
const app = koa ( feathers ())
app . use ( bodyParser ())
// Use Koa router
const router = new Router ()
router . get ( '/status' , ( ctx ) => {
ctx . body = { status: 'ok' , uptime: process . uptime () }
})
app . use ( router . routes ())
app . use ( router . allowedMethods ())
// Configure Feathers REST
app . configure ( rest ())
// Register Feathers services
app . use ( '/api/todos' , todoService )
Lifecycle Methods
listen()
setup()
teardown()
The listen() method starts the server and calls setup() on all services: const server = await app . listen ( 3030 )
console . log ( 'Server started on port 3030' )
Manually call setup() when using a custom server: import http from 'http'
const server = http . createServer ( app . callback ())
await app . setup ( server )
server . listen ( 3030 )
Clean shutdown closes the HTTP server and calls teardown on services: // Graceful shutdown
process . on ( 'SIGTERM' , async () => {
await app . teardown ()
console . log ( 'Server stopped' )
process . exit ( 0 )
})
TypeScript Support
import { feathers , Service } from '@feathersjs/feathers'
import { koa , Application } from '@feathersjs/koa'
interface User {
id : number
email : string
name : string
}
interface ServiceTypes {
users : Service < User >
}
const app : Application < ServiceTypes > = koa ( feathers ())
app . use ( '/users' , {
async find () {
return [{ id: 1 , email: 'user@example.com' , name: 'User' }]
}
})
await app . listen ( 3030 )
Middleware Execution Order
Understanding middleware order is crucial in Koa:
import { koa , rest , bodyParser , errorHandler } from '@feathersjs/koa'
const app = koa ( feathers ())
// 1. Error handler (first to catch all errors)
app . use ( errorHandler ())
// 2. Global middleware
app . use ( async ( ctx , next ) => {
console . log ( 'Request:' , ctx . method , ctx . path )
await next ()
console . log ( 'Response:' , ctx . status )
})
// 3. Body parser
app . use ( bodyParser ())
// 4. REST configuration (sets up service routing)
app . configure ( rest ())
// 5. Custom routes
app . use ( async ( ctx , next ) => {
if ( ctx . path === '/custom' ) {
ctx . body = { custom: true }
} else {
await next ()
}
})
// 6. Services (handled by REST transport)
app . use ( '/users' , userService )
API Reference
koa(feathersApp?, koaApp?)
Wraps a Feathers application with Koa.
Parameters:
feathersApp - A Feathers application instance
koaApp - Optional existing Koa app
Returns: Combined Feathers + Koa application
rest(options?)
Configures the REST transport.
Options:
formatter - Custom response formatter middleware
authentication - Authentication settings
service - Authentication service name
strategies - Array of strategy names
errorHandler()
Koa error handling middleware that catches errors and formats them as JSON.
bodyParser(options?)
Parses request bodies. Wraps koa-body.
Options: See koa-body documentation
cors(options?)
Enables CORS. Wraps @koa/cors.
Options: See @koa/cors documentation