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 now- ServerEvent
- 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