Endpoint Middleware
See original GitHub issueDescribe the problem
I would like to propose a better model for endpoints middleware rather than the global hooks
.
Current state: Today, we only have what appears to be one (1) hook src/hooks.ts
that is run every time SvelteKit receives a request.
Issue: While this is ok for general things such as checking for authentication with a pathname
e.g., check_auth if pathname.startsWith('/admin')
. The handle becomes quite large and unwieldy to check each pathname, etc.
Describe the proposed solution
Proposal: Permit the creation of one (1) hook per Endpoint in addition to the globally defined hook.
// src/routes/user.hook.ts
// This file can be used to perform a logic for this endpoint only
export async function handle({event, resolve}) {
const {method, body} = event.request;
// get to the page if GET request
if (method === 'GET') return resolve(event);
try {
await validate(body)
return resolve(event)
} catch (error) {
return Response(JSON.stringify(e), {status: 422})
}
}
The sequence for Sveltekit hooks would be as follows
src/hooks.ts -> src/{endpoint}.hook.{ts/js} -> src/{endpoint}.{ts/js} -> src/{endpoint}.svelte
This would provide a nice global hook with the additional benefits of a hook per endpoint.
Alternatives considered
Current implementation is as follows and is a terrible experience.
export async function handle({event, resolve}) {
const route = event.url.pathname
const {method, body} = event.request;
switch (route) {
case '/users':
if (method === 'GET') return resolve(event);
try {
await validateUserBody(body)
return resolve(event)
} catch (error) {
return Response(JSON.stringify(e), {status: 422})
}
break;
case '/notes':
if (method === 'GET') return resolve(event);
try {
await validateNotesBody(body)
return resolve(event)
} catch (error) {
return Response(JSON.stringify(e), {status: 422})
}
break;
.... other endpoints....
}
}
### Importance
would make my life easier
### Additional Information
I think this feature would be nice to have too many of the developers that are using Sveltekit today.
Issue Analytics
- State:
- Created 2 years ago
- Reactions:7
- Comments:6 (3 by maintainers)
I’ve implemented my own middleware solution that works both for page component
load
and endpoint handlers. You basically create a function that returns a endpoint handler, import that function in your endpoints and pass your handler function as a parameter:@f-elix yes, looked at it, but won’t solve the exact problem I outlined above. While I could create each handle and use sequence, this is not exactly performant as it would run all of the handles in
sequence
. And, while you can have an escape hatch for the handle by checking for the pathname as the first thing, it is still not an optimal solution - which is why I propose a separatehook
ormiddleware
file that can be used/called for eachendpoint
.The call graph, for lack of a better term, using sequence is roughly
src/hooks[n] -> src/routes/user.ts -> src/routes/user.svelte
. As you can see here, the sequence model is to n - an unbounded number.Whereas my call graph would be
src/hooks[1] -> src/routes/user.hooks.ts -> src/routes/user.ts -> src/routes/user.svelte
as you can see, by separating the flow of the hooks “middleware” we have 1 global although it could be more, and 1 for the user endpoint. The call flow is much easier to grok, I know that things like ensuring authentication should be in the global hook, and things specific to my user should be in the user.hook.