Skip to content

Commit

Permalink
Route Handler Types (#57070)
Browse files Browse the repository at this point in the history
This updates the handle functions on the server to share a common type that simplifies the signature.
  • Loading branch information
wyattjoh authored Oct 20, 2023
1 parent aa1ee59 commit 354705d
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 135 deletions.
124 changes: 44 additions & 80 deletions packages/next/src/server/base-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,12 @@ export interface MiddlewareRoutingItem {
matchers?: MiddlewareMatcher[]
}

export type RouteHandler = (
req: BaseNextRequest,
res: BaseNextResponse,
parsedUrl: NextUrlWithParsedQuery
) => PromiseLike<boolean> | boolean

/**
* The normalized route manifest is the same as the route manifest, but with
* the rewrites normalized to the object shape that the router expects.
Expand Down Expand Up @@ -521,17 +527,17 @@ export default abstract class Server<ServerOptions extends Options = Options> {
return this.matchers.reload()
}

protected async handleNextDataRequest(
req: BaseNextRequest,
res: BaseNextResponse,
parsedUrl: NextUrlWithParsedQuery
): Promise<{ finished: boolean }> {
protected handleNextDataRequest: RouteHandler = async (
req,
res,
parsedUrl
) => {
const middleware = this.getMiddleware()
const params = matchNextDataPathname(parsedUrl.pathname)

// ignore for non-next data URLs
if (!params || !params.path) {
return { finished: false }
return false
}

if (params.path[0] !== this.buildId) {
Expand All @@ -540,12 +546,12 @@ export default abstract class Server<ServerOptions extends Options = Options> {
process.env.NEXT_RUNTIME !== 'edge' &&
req.headers['x-middleware-invoke']
) {
return { finished: false }
return false
}

// Make sure to 404 if the buildId isn't correct
await this.render404(req, res, parsedUrl)
return { finished: true }
return true
}

// remove buildId from URL
Expand All @@ -556,9 +562,7 @@ export default abstract class Server<ServerOptions extends Options = Options> {
// show 404 if it doesn't end with .json
if (typeof lastParam !== 'string' || !lastParam.endsWith('.json')) {
await this.render404(req, res, parsedUrl)
return {
finished: true,
}
return true
}

// re-create page's pathname
Expand Down Expand Up @@ -610,38 +614,26 @@ export default abstract class Server<ServerOptions extends Options = Options> {
if (!localePathResult.detectedLocale && !middleware) {
parsedUrl.query.__nextLocale = defaultLocale
await this.render404(req, res, parsedUrl)
return { finished: true }
return true
}
}

parsedUrl.pathname = pathname
parsedUrl.query.__nextDataReq = '1'

return { finished: false }
return false
}

protected async handleNextImageRequest(
_req: BaseNextRequest,
_res: BaseNextResponse,
_parsedUrl: NextUrlWithParsedQuery
): Promise<{ finished: boolean }> {
return { finished: false }
protected handleNextImageRequest: RouteHandler = () => {
return false
}

protected async handleCatchallRenderRequest(
_req: BaseNextRequest,
_res: BaseNextResponse,
_parsedUrl: NextUrlWithParsedQuery
): Promise<{ finished: boolean }> {
return { finished: false }
protected handleCatchallRenderRequest: RouteHandler = () => {
return false
}

protected async handleCatchallMiddlewareRequest(
_req: BaseNextRequest,
_res: BaseNextResponse,
_parsedUrl: NextUrlWithParsedQuery
): Promise<{ finished: boolean }> {
return { finished: false }
protected handleCatchallMiddlewareRequest: RouteHandler = () => {
return false
}

protected getRouteMatchers(): RouteMatcherManager {
Expand Down Expand Up @@ -1072,15 +1064,8 @@ export default abstract class Server<ServerOptions extends Options = Options> {
parsedUrl.pathname = matchedPath
url.pathname = parsedUrl.pathname

const normalizeResult = await this.handleNextDataRequest(
req,
res,
parsedUrl
)

if (normalizeResult.finished) {
return
}
const finished = await this.handleNextDataRequest(req, res, parsedUrl)
if (finished) return
} catch (err) {
if (err instanceof DecodeError || err instanceof NormalizeError) {
res.statusCode = 400
Expand Down Expand Up @@ -1244,26 +1229,14 @@ export default abstract class Server<ServerOptions extends Options = Options> {
)
}

if (parsedUrl.pathname.startsWith('/_next/image')) {
const imageResult = await this.handleNextImageRequest(
req,
res,
parsedUrl
)
// Try to handle this as a `/_next/image` request.
let finished = await this.handleNextImageRequest(req, res, parsedUrl)
if (finished) return

if (imageResult.finished) {
return
}
}
const nextDataResult = await this.handleNextDataRequest(
req,
res,
parsedUrl
)
// Try to handle the request as a `/_next/data` request.
finished = await this.handleNextDataRequest(req, res, parsedUrl)
if (finished) return

if (nextDataResult.finished) {
return
}
await this.handleCatchallRenderRequest(req, res, parsedUrl)
return
}
Expand All @@ -1272,35 +1245,26 @@ export default abstract class Server<ServerOptions extends Options = Options> {
process.env.NEXT_RUNTIME !== 'edge' &&
req.headers['x-middleware-invoke']
) {
const nextDataResult = await this.handleNextDataRequest(
req,
res,
parsedUrl
)
let finished = await this.handleNextDataRequest(req, res, parsedUrl)
if (finished) return

if (nextDataResult.finished) {
return
}
const result = await this.handleCatchallMiddlewareRequest(
finished = await this.handleCatchallMiddlewareRequest(
req,
res,
parsedUrl
)
if (finished) return

if (result.finished) {
return
} else {
const err = new Error()
;(err as any).result = {
response: new Response(null, {
headers: {
'x-middleware-next': '1',
},
}),
}
;(err as any).bubble = true
throw err
const err = new Error()
;(err as any).result = {
response: new Response(null, {
headers: {
'x-middleware-next': '1',
},
}),
}
;(err as any).bubble = true
throw err
}

// ensure we strip the basePath when not using an invoke header
Expand Down
Loading

0 comments on commit 354705d

Please sign in to comment.