Overview
Version 7 of the API plugin introduces major changes that modernize and simplify route management. This update aims to make API development more intuitive, faster, and aligned with current web standards.
Key highlights:
- File-system-based routing: Routes are automatically generated from your folder and file structure.
- Simplified HTTP method definition: Specify the HTTP method directly in the filename (e.g.,
users.get.tsfor a GET route). - Modern route parameters: Use
[param]syntax instead of:paramfor dynamic segments (e.g.,/guilds/[guild]). - Direct request handling: The
MediaParseris removed; use new parsing methods on the request object. - Standardized MIME types: Adoption of IANA MIME types for better compatibility.
These changes make API creation clearer, safer, and easier to maintain.
Breaking Changes
Removal of Media Parser
- The
MediaParserandMediaParserStoreclasses are removed. - The
Route#acceptedContentMimeTypesproperty no longer exists. - The
ApiRequest#bodyproperty is removed: use the new async parsing methods (request.readBody(),request.readBodyJson(),,etc.).
Migration example:
// Before (v6)
const data = request.body;
// After (v7)
const data = await request.readBody();
MIME Types Update
- The
MimeTypesenum is replaced by a string union type (MimeType) using IANA types (e.g.,"application/json").
Routing System Changes
Event and Property Renaming
ServerEventsis nowServerEvent- The
matchevent is nowrouterFound - The
noMatchevent is nowrouterBranchNotFound
Other Modifications
RouteStore#matchis now a listener.- The
node:eventsmodule is replaced by@vladfrangu/async_event_emitter. - The
routeparameter inMiddleware#runis removed: userequest.route. - The
Route#routerandRouteStore#methodsproperties are removed. - Route event objects are removed: use
request.routeandrequest.routerNode.
HTTP Method Handling
- The
headersmiddleware now uses the HTTP methods supported by the route or store. - The
Routeclass no longer matches by method name. - HTTP methods are defined in the filename:
<name>.<method>.ts(e.g.,user.post.ts).
Route and Path Management
- Prefixes are now suffixed with
/before concatenation inRouteData. - If
options.routeis not set, the route defaults to the file path. - Route parameters use
/guilds/[guild]syntax instead of/guilds/:guild.
Example: Migrating a Route
Here's how to convert an existing route from v6 to v7:
// Before (v6)
// ../index.ts
import { ApiRequest, ApiResponse, methods, MimeTypes, Route } from '@sapphire/plugin-api';
export class UserRoute extends Route {
public acceptedContentMimeTypes = [MimeTypes.ApplicationJson];
public async [methods.GET](request: ApiRequest, response: ApiResponse) {
const data = request.body;
// ...
}
}
// After (v7)
// ../index.get.ts
import { ApiRequest, ApiResponse, Route } from '@sapphire/plugin-api';
export class UserRoute extends Route {
public async run(request: ApiRequest, response: ApiResponse) {
const data = await request.readBodyJson();
// ...
}
}
Filesystem Group Syntax
v7 introduces a new, intuitive filesystem-based group syntax. For example:
routes/
├── guilds/
│ ├── [guild]/
│ │ └── members.get.ts
│ └── index.get.ts
└── users/
└── @me.get.ts
This structure automatically generates the following routes:
/guilds/[guild]/members/guilds/users/@me