Rewrite in ESM
Pre-releaseHighlights
- Added a new layer of middleware called server middleware. Server middleware runs before the route matching happens. So now, we have three types of middleware.
- Server: Runs for all the HTTP requests.
- Router: Runs for all the HTTP requests only if a route for the request URL is defined.
- Named: Individually applied on the routes.
- Code is way faster than earlier. However, keeping fastify as the performance benchmark, we are 2%-3% slower than fastify.
- The internals are a lot simpler. We have removed around 3000 lines of code (though we have added many more tests).
- No longer using ambient modules. Ambient modules was a hack to get
@ioc
style imports to work. - Introduced a new layer of middleware stack called server middleware. Server middleware runs on all HTTP requests, even if no routes for that URL exist.
- Allow configuring the query string parser and serializer.
Breaking changes
- The code is rewritten in ESM and will not work with CJS anymore
- A lot of interfaces have been removed. So, for example, instead of using
HttpContextContract
you can import and use theHttpContext
class directly for type annotation. - Removed
standalone.ts
export. Instead, the main entry point now exports everything (except types). - The types are exported from the
/types
subpath. - Removed all providers. The AdonisJS core will be creating providers for all the underlying packages.
- Removed the
forceContentNegotiationTo
config option. Instead, we will ship with a default middleware to force content negotiation.
Router - Breaking changes
-
Removed the
Route.namespace
method. We no longer use the concept of namespaces in favor of Node.js sub-path imports. -
Underlying storage of routes has changed. Each route's
middleware
property is no longer an array of names and arguments. Instead, it is an instance of theMiddleware
class. Also, the route middleware is now a list of the router's global middleware + route's middleware.// Earlier const routesJSON = router.toJSON() routesJSON[0].middleware.map(({ name, args }) => {}) // Now const routesJSON = router.toJSON() const routeMiddleware = [...routesJSON[0].middleware.all()] routeMiddleware.forEach((middleware) => { if (typeof middleware === 'function') { // Middleware defined on the route as a function } if (middleware.name) { // Named middleware defined on the route } // else it is a global middleware })
-
Remove the
Route.resource.paramFor
method in favor of theRoute.resource.params
method. The latter allows overwriting param names in bulk.// Earlier Route .resource('posts.comments', 'CommentsController') .paramFor('posts', 'post') .paramFor('comments', 'comment') // Now Route .resource('posts.comments', '#controllers/comments') .params({ 'posts': 'post', comments: 'comment' })
-
Remove the
Route.resource.middleware
method in favor ofRoute.resource.tap
. The tap method allows you to access the underlying route for a given resource action.// Earlier Route .resource('posts', 'PostsController') .middleware({ '*': 'auth', create: ['acl:admin'], update: ['acl:admin'], destroy: ['acl:admin'], }) // Now Route .resource('posts', 'PostsController') .tap((route) => { route.middleware('auth') }) .tap(['create', 'update', 'destroy'], (route) => { route.middleware('acl', { role: 'admin' }) })
-
Remove
Route.name
andRoute.deleted
properties in favor ofRoute.getName()
andRoute.isDeleted()
methods.
Middleware breaking change
-
The
Route.middleware
method now has type safety. The method will list all the available middleware and the options accepted by them. Also, the middleware options will be passed as a separate argument. Earlier, we used to concatenate the options within the middleware name.// Earlier Route .get('me', 'ProfileController.show') .middleware('auth:web') // Now Route .get('me', 'ProfileController.show') .middleware('auth', { guard: 'web' })
Multiple middleware needs to be defined by calling the
middleware
method multiple times.// Earlier Route .get('me', 'ProfileController.show') .middleware(['auth:web', 'acl:admin']) // Now Route .get('me', 'ProfileController.show') .middleware('auth', { guard: 'web' }) .middleware('role', { role: 'admin' })
-
Remove properties
BriskRoute
,RouteGroup
,RouteResource
,Route
, andRouteMatchers
from the router class. You will have to import these classes separately.// Earlier import Route from '@ioc:Adonis/Core/Route' Route.RouteGroup.macro() Route.RouteResource.macro() // Now import { RouteGroup, RouteResource } from '@adonisjs/core/http' RouteGroup.macro() RouteResource.macro()
-
The
Route.makeUrl
andRoute.makeSignedUrl
no longer accept deprecated options. Therefore, if currently using these methods does not give any deprecation warnings, you will not see any breaking changes here.
Http Context breaking changes
- Remove the
HttpContext.create
static method. The method was helpful during testing to create a fake instance of HTTP context. We will be shipping with a factory to create the HTTP context.
Server - Breaking changes
- Removed
Server.hooks
in favor of Server middleware. They were never documented because we knew hooks were a makeshift arrangement. - Removed
middleware
property. Middleware is not defined using thedefineMiddleware
anddefinedNamedMiddleware
methods. - Remove
Server.optimize
in favor of asyncServer.boot
method. - Remove the
server.instance
property in favor of theserver.getNodeServer
method. - Remove the
server.router
property in favor of theserver.getRouter
method.
Request breaking changes
- Remove
request.updateParams
. Therequest.params
method reads the params from the HttpContext and does not maintain its copy anymore. - Remove deprecated
request.get
andrequest.post
methods.
Response - Breaking changes
-
Changed the data structure of the
response.lazyBody
property. It is now an object with known properties.// Earlier const responseContent = response.lazyBody[0] // Now if (response.lazyContent.content) const responseContent = response.lazyContent.content[0] }
Commits
- feat: add defineMiddleware and defineNamedMiddleware helpers 890b7c3
- feat: add support to customize the query string parser da8a24c
- feat: allow configuring the query string parser 3b85adc
- test: improve coverage 854a478
- refactor: move config normalization to defineConfig method c46b254
- refactor: make router and instance properties private 901060f
- refactor: small improvements in the server 81c1cb9
- refactor: remove redundant custom exceptions 31a4441
- docs(README): update readme file 0dac61f
- feat: main define_config helper and main exports 11b8b79
- refactor: increase cool off time between benchmarks 7027c9e
- test: skip test that needs on-demand SSL certificates c4f6d4f
- chore: use cross-env to set env variables ecb40e0
- chore: fix peer dependencies range 671ec52
- refactor: bunch of improvements 0848671
- refactor: a huge refactor f089f57
- refactor: the routing layer a8dba96
Full Changelog: v5.12.0...v6.0.0-0