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.ts
for a GET route). - Modern route parameters: Use
[param]
syntax instead of:param
for dynamic segments (e.g.,/guilds/[guild]
). - Direct request handling: The
MediaParser
is 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
MediaParser
andMediaParserStore
classes are removed. - The
Route#acceptedContentMimeTypes
property no longer exists. - The
ApiRequest#body
property 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
MimeTypes
enum is replaced by a string union type (MimeType
) using IANA types (e.g.,"application/json"
).
Routing System Changes
Event and Property Renaming
ServerEvents
is nowServerEvent
- The
match
event is nowrouterFound
- The
noMatch
event is nowrouterBranchNotFound
Other Modifications
RouteStore#match
is now a listener.- The
node:events
module is replaced by@vladfrangu/async_event_emitter
. - The
route
parameter inMiddleware#run
is removed: userequest.route
. - The
Route#router
andRouteStore#methods
properties are removed. - Route event objects are removed: use
request.route
andrequest.routerNode
.
HTTP Method Handling
- The
headers
middleware now uses the HTTP methods supported by the route or store. - The
Route
class 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.route
is 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