-
Notifications
You must be signed in to change notification settings - Fork 0
Patches
Patches are designed to separate logic between accepting the request and generating the response. The pattern we
recommend is that your entry
function is in charge of parsing URL parameters and query strings, setting defaults,
etc. and putting all necessary data in one place for your exit
function to use, so that the exit
function is
guaranteed to succeed.
In fact, we've included an easy way to guarantee data safety for exit
. entry
returns
a generic type, though you may not initially realize it because it defaults to void
.
A more realistic and data-safe version of the UserPage example in the template project might look something like this:
interface UserPageData {
username: string;
followerCount: number;
bio: string;
}
class UserPage extends Patch<UserPageData> {
async entry(req: PBRequest): Promise<UserPageData> {
this.parseRouteParams(req);
const username = this.routeParameters.username;
const data = await database.users.get(username);
if (data === null)
throw PBUtils.TemplateResponse("user-not-found", {user: username});
return {
username: username,
followerCount: data.followerCount,
bio: data.bio
}
}
exit(data: UserPageData): Response {
return PBUtils.TemplateResponse('user-page', data);
}
}
...
...
Note: there is a related public function called __safe_intercept
, which should not be overridden or used by you. This is only used internally by PatchBay.
This function is generally for edge cases, but can be very useful. It's a special function that allows the Patch to return control to the router and fall through before it runs. Think of the name as a question: if you want it to intercept and hand control back to the parent, return true
; if you want it to continue without intercepting, return false
.
You can use this
inside intercept
, but the properties will not be preserved from the last time the patch ran, nor will they be preserved for the next run, so use it carefully and sparingly.
One use of this function is to have separate patches for different HTTP methods on the same route:
class GetTweet extends Patch {
intercept(req: PBRequest): boolean {
return req.method !== "GET"
}
// ...
}
class PostTweet extends Patch {
intercept(req: PBRequest): boolean {
return req.method !== "POST"
}
// ...
}
class CatchallTweet extends Patch {
// leave intercept undefined
// ...
}
// Then the router's patchables should look like:
[
new GetTweet("/tweet"),
new PostTweet("/tweet"),
new CatchallTweet("/tweet")
]