icon |
---|
icons8:up-round |
h3 v2 includes some behavior and API changes that you need to consider applying when migrating.
Note
Currently v2 is in beta stage You can try with h3-nightly@2x
Note
This is an undergoing migration guide and is not finished yet.
H3 v2 is now web-native and you can directly use app.fetch(request, init)
.
Old utils for plain handler and web handler are removed to embrace web standards.
Event Properties event.node.{req,res}
and event.web
are not available anymore, instead, you can use getNodeContext(event)
and getWebContext(event)
utils to access raw objects for each runtime.
event.handler
property is removed since h3 relies on explicit responses.
You should always explicitly use return
for response and throw
for errors from event handlers.
If you were previously using these methods, you can replace them with return
statements returning a text, JSON, stream, or web Response
(h3 smartly detects and handles them):
send(event, value)
: Migrate toreturn <value>
.sendError(event, <error>)
: Migrate tothrow createError(<error>)
.sendStream(event, <stream>)
: Migrate toreturn <stream>
.sendWebResponse(event, <response>)
: Migrate toreturn <response>
.
Other send utils that are renamed and need explicit return
:
sendNoContent(event)
/return null
: Migrate toreturn noContent(event)
.sendIterable(event, <value>)
: Migrate toreturn iterable(<value>)
.sendRedirect(event, location, code)
: Migrate toreturn redirect(event, location, code)
.sendProxy(event, target)
: Migrate toreturn proxy(event, target)
.handleCors(event)
: Check return value (boolean) and earlyreturn
if handled.serveStatic(event, content)
: Make sure to addreturn
before.
Router functionality is now integrated into the h3 app core. Instead of createApp()
and createRouter()
you can use const app = createH3()
.
Methods:
app.use(handler)
: Add a global middleware.app.use(route, handler)
: Add a routed middleware.app.on(method, handler)
/app.all(handler)
/app.[METHOD](handler)
: Add a route handler.
Running order:
- All global middleware in the same order they added
- All routed middleware from least specific to most specific paths (auto-sorted)
- Matched route handler
Any middleware or route handler can return a response.
Other changes from v1:
- Handlers registered with
app.use("/path", handler)
only match/path
(not/path/foo/bar
). For matching all subpaths like before, it should be updated toapp.use("/path/**", handler)
. - The
event.path
received in each handler will have a full path without omitting the prefixes. usewithBase(base, handler)
utility to make prefixed app. (example:withBase("/api", app.handler)
). app.use(() => handler, { lazy: true })
is no supported anymore. Instead you can useapp.use(defineLazyEventHandler(() => handler), { lazy: true })
app.use(["/path1", "/path2"], ...)
andapp.use("/path", [handler1, handler2])
are not supported anymore. Instead, use multipleapp.use()
calls.- Custom
match
function forapp.use
is not supported anymore (middleware can skip themselves). app.resolve(path) => { route, handler }
changed toapp.resolve(method, path) => { method route, handler }
h3 migrated to a brand new route-matching engine unjs/rou3.
You might experience slight (and more intuitive) behavior changes for matching patterns.
router.use(path, handler)
is deprecated. Userouter.all(path, handler)
instead.router.add(path, method: Method | Method[]
signature is changed torouter.add(method: Method, path)
(important)
The legacy readBody
and readRawBody
utils are replaced with a new set of body utils that can leverage native runtime primitives better.
readRawBody
: Returns body asUint8Array
which is similar to Node.jsBuffer
.readTextBody
: Returns body as text (utf8
).readJSONBody
/readValidatedJSONBody
: Returns JSON value of the body usingJSON.parse
orURLSearchParams
forform-urlencoded
readFormDataBody
: Returns body parsed as FormData.getBodyStream
: Returns body as aReadableStream
, replacing older experimentalgetRequestWebStream
: Util.
Behavior changes:
- Body utils won't throw an error if the incoming request has no body (or is a
GET
method for example) but instead, returnsundefined
readJSONBody
does not use unjs/destr anymore. You should always filter and sanitize data coming from user to avoid prototype-poisoning
h3 migrated to leverage standard web Headers
for all utils.
Header values are always a plain string
now (no null
or undefined
or number
or string[]
).
For the Set-Cookie
header, you can use headers.getSetCookie
that always returns a string array.
h3 v2 deprecated some legacy and aliased utilities.
App and router:
createRouter
: Migrate tocreateH3
createApp
: Migrate tocreateH3
Handler:
eventHandler
: Migrate todefineEventHandler
lazyEventHandler
: Migrate todefineLazyEventHandler
useBase
: Migrate towithbase
toEventHandler
/isEventHandler
: (removed) Any function can be an event handler.
Request:
getHeader
: Migrate togetRequestHeader
.getHeaders
: Migrate togetRequestHeaders
.getRequestPath
: Migrate toevent.path
.
Response:
appendHeader
: Migrate toappendResponseHeader
.appendHeaders
: Migrate toappendResponseHeaders
.setHeader
: Migrate tosetResponseHeader
.setHeaders
: Migrate tosetResponseHeaders
.
Node.js:
defineNodeListener
: Migrate todefineNodeHandler
.fromNodeMiddleware
: Migrate tofromNodeHandler
.toNodeListener
: Migrate totoNodeHandler
.createEvent
: (removed): Use Node.js adapter (toNodeHandler(app)
).fromNodeRequest
: (removed): Use Node.js adapter (toNodeHandler(app)
).promisifyNodeListener
(removed).callNodeListener
: (removed).
Web:
fromPlainHandler
: (removed) Migrate to Web API.toPlainHandler
: (removed) Migrate to Web API.fromPlainRequest
(removed) Migrate to Web API or usemockEvent
util for testing.callWithPlainRequest
(removed) Migrate to Web API.fromWebRequest
: (removed) Migrate to Web API.callWithWebRequest
: (removed).
Body:
-
readBody
: Migrate toreadJSONBody
. -
readFormData
: Migrate toreadFormDataBody
. -
readValidatedBody
: Migrate toreadValidatedJSONBody
. -
getRequestWebStream
: Migrate togetBodyStream
. -
readMultipartFormData
: Migrate toreadFormDataBody
. -
Utils:
-
isStream
: Migrate toinstanceof ReadableStream
and.pipe
properties for detecting Node.jsReadableStream
. -
isWebResponse
: Migrate touse instanceof Response
. -
MIMES
: (removed).
Types:
App
: Migrate toH3
.AppOptions
: Migrate toH3Config
._RequestMiddleware
: Migrate toRequestMiddleware
._ResponseMiddleware
: Migrate toResponseMiddleware
.NodeListener
: Migrate toNodeHandler
.TypedHeaders
: Migrate toRequestHeaders
andResponseHeaders
.HTTPHeaderName
: Migrate toRequestHeaderName
andResponseHeaderName
.H3Headers
: Migrate to nativeHeaders
.H3Response
: Migrate to nativeResponse
.MultiPartData
: Migrate to nativeFormData
.RouteNode
: Migrate toRouterEntry
.CreateRouterOptions
: Migrate toRouterOptions
.
Removed type exports: WebEventContext
, NodeEventContext
, NodePromisifiedHandler
, AppUse
, Stack
, InputLayer
, InputStack
, Layer
, Matcher
, PlainHandler
, PlainRequest
, PlainReponse
, WebHandler