Koa Method Override Middleware

raw JSON →
4.0.0 verified Thu Apr 23 auth: no javascript

koa-override is a Koa middleware designed to enable clients to utilize HTTP verbs like PUT or DELETE in environments where direct support is limited, typically by overriding the method via a `_method` field in the request body or an `X-HTTP-Method-Override` header. The current stable version is 4.0.0, released in June 2024. This package is maintained by the Egg.js team, indicating active development and stability within the Koa ecosystem. It provides a simple API, `override([options])`, allowing configuration of allowed override methods (defaulting to `POST` requests). A key differentiator is its explicit method overriding mechanism, making it a robust solution for RESTful API compatibility challenges with legacy clients or specific network constraints. It ships with TypeScript types and supports both CommonJS and ES Modules since version 4.0.0.

error TypeError: override is not a function
cause The `override` import refers to the middleware factory, which must be called to produce the actual middleware.
fix
Change app.use(override) to app.use(override()).
error Method override not working when using _method in form data
cause The request body, containing `_method`, has not been parsed yet when `koa-override` attempts to read it.
fix
Add a body parser middleware, like koa-bodyparser, before koa-override. Example: app.use(bodyParser()); app.use(override());
error Method override not working for GET requests or other non-POST methods
cause By default, `koa-override` only applies method overriding to `POST` requests.
fix
Configure koa-override with the allowedMethods option to include the desired request types, e.g., app.use(override({ allowedMethods: ['POST', 'GET'] }));
breaking Version 4.0.0 drops support for Node.js versions older than 18.19.0. Projects on older Node.js versions must upgrade Node.js or remain on `koa-override` v3.
fix Upgrade Node.js to version 18.19.0 or higher, or explicitly install `koa-override@3`.
gotcha To override methods using the `_method` field in the request body (e.g., from an HTML form), a body parsing middleware like `koa-bodyparser` is required to parse the request body before `koa-override` can access it.
fix Ensure `koa-bodyparser` or a similar body parser middleware is used *before* `koa-override` in your middleware chain: `app.use(bodyParser()); app.use(override());`
gotcha By default, `koa-override` only allows method overriding on `POST` requests. Attempts to override methods on `GET` or other request types will be ignored unless `options.allowedMethods` is configured.
fix If you need to override methods on non-POST requests, configure `koa-override` with `app.use(override({ allowedMethods: ['POST', 'GET', 'PATCH'] }));`
npm install koa-override
yarn add koa-override
pnpm add koa-override

Demonstrates setting up a basic Koa application with `koa-override` and `koa-bodyparser` to allow method overriding via request body (`_method`) or HTTP header (`X-HTTP-Method-Override`).

import Koa from 'koa';
import bodyParser from 'koa-bodyparser';
import override from 'koa-override';

const app = new Koa();

// Add a body parser to handle _method in the request body
app.use(bodyParser());

// Apply the method override middleware
// By default, it checks `body._method` then `X-HTTP-Method-Override` header
// Overrides are only allowed on POST requests by default.
app.use(override());

app.use(async (ctx, next) => {
  if (ctx.method === 'DELETE') {
    ctx.body = `Received a simulated DELETE request for ${ctx.url}`;
  } else if (ctx.method === 'PUT') {
    ctx.body = `Received a simulated PUT request for ${ctx.url} with body: ${JSON.stringify(ctx.request.body)}`;
  } else {
    await next();
  }
});

app.use(async (ctx) => {
  ctx.body = `Received original ${ctx.method} request for ${ctx.url}`;
});

const port = 3000;
app.listen(port, () => {
  console.log(`Server listening on http://localhost:${port}`);
  console.log('Try POSTing to /test with X-HTTP-Method-Override: PUT, or with body: { "_method": "DELETE" }');
});