Clean up middleware; solidify support for route handler classes
This commit is contained in:
parent
ff34578d07
commit
27ee1a552b
@ -1,5 +1,12 @@
|
|||||||
import Middleware from '../../../lib/src/http/Middleware.ts'
|
import Middleware from '../../../lib/src/http/Middleware.ts'
|
||||||
|
import {Request} from '../../../lib/src/http/Request.ts'
|
||||||
|
import {http} from '../../../lib/src/http/response/helpers.ts'
|
||||||
|
import {HTTPStatus} from '../../../lib/src/const/http.ts'
|
||||||
|
|
||||||
export default class TestMiddleware extends Middleware {
|
export default class TestMiddleware extends Middleware {
|
||||||
|
public async handleRequest(request: Request) {
|
||||||
|
if ( Math.random() >= 0.5 ) {
|
||||||
|
return http(HTTPStatus.FORBIDDEN, 'Well, you were unlucky.')
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,5 +5,6 @@ export default {
|
|||||||
middleware: [],
|
middleware: [],
|
||||||
get: {
|
get: {
|
||||||
'/': 'controller::Home.get_home',
|
'/': 'controller::Home.get_home',
|
||||||
|
'/maybe': ['middleware::Test', 'controller::Home.get_home'],
|
||||||
},
|
},
|
||||||
} as RouterDefinition
|
} as RouterDefinition
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
import AppClass from '../lifecycle/AppClass.ts'
|
import AppClass from '../lifecycle/AppClass.ts'
|
||||||
|
import {Request} from './Request.ts'
|
||||||
|
import {RouteHandlerReturnValue} from '../unit/Routing.ts'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class for HTTP middleware.
|
* Base class for HTTP middleware.
|
||||||
@ -6,4 +8,13 @@ import AppClass from '../lifecycle/AppClass.ts'
|
|||||||
*/
|
*/
|
||||||
export default class Middleware extends AppClass {
|
export default class Middleware extends AppClass {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the incoming request and apply this middleware.
|
||||||
|
* @param {Request} request
|
||||||
|
* @return RouteHandlerReturnValue
|
||||||
|
*/
|
||||||
|
public handleRequest(request: Request): RouteHandlerReturnValue {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ import {Request} from '../../Request.ts'
|
|||||||
import ResponseFactory from '../../response/ResponseFactory.ts'
|
import ResponseFactory from '../../response/ResponseFactory.ts'
|
||||||
import {http, error} from '../../response/helpers.ts'
|
import {http, error} from '../../response/helpers.ts'
|
||||||
import {HTTPStatus} from '../../../const/http.ts'
|
import {HTTPStatus} from '../../../const/http.ts'
|
||||||
|
import {isRouteHandlerClass} from "../../../unit/Routing.ts";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* HTTP kernel module to apply route handlers to the incoming request.
|
* HTTP kernel module to apply route handlers to the incoming request.
|
||||||
@ -47,7 +48,13 @@ export default class ApplyRouteHandlers extends Module {
|
|||||||
let current_request: Request = request
|
let current_request: Request = request
|
||||||
for ( const handler of request.route.handlers ) {
|
for ( const handler of request.route.handlers ) {
|
||||||
try {
|
try {
|
||||||
const result = await handler(current_request)
|
let result
|
||||||
|
if ( isRouteHandlerClass(handler) ) {
|
||||||
|
result = await handler.handleRequest(current_request)
|
||||||
|
} else {
|
||||||
|
result = await handler(current_request)
|
||||||
|
}
|
||||||
|
|
||||||
if ( result instanceof Request ) {
|
if ( result instanceof Request ) {
|
||||||
// If we got a request instance back, use that for further handlers
|
// If we got a request instance back, use that for further handlers
|
||||||
current_request = result
|
current_request = result
|
||||||
|
@ -16,10 +16,22 @@ import {isBindable} from '../lifecycle/AppClass.ts'
|
|||||||
import {DeepmatchRoute} from "../http/routing/DeepmatchRoute.ts";
|
import {DeepmatchRoute} from "../http/routing/DeepmatchRoute.ts";
|
||||||
import {RegExRoute} from "../http/routing/RegExRoute.ts";
|
import {RegExRoute} from "../http/routing/RegExRoute.ts";
|
||||||
|
|
||||||
|
export type RouteHandlerReturnValue = SyncRouteHandlerReturnValue | AsyncRouteHandlerReturnValue
|
||||||
|
export type SyncRouteHandlerReturnValue = Request | ResponseFactory | void | undefined
|
||||||
|
export type AsyncRouteHandlerReturnValue = Promise<SyncRouteHandlerReturnValue>
|
||||||
|
export type RouteHandlerFunction = (request: Request) => RouteHandlerReturnValue
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A class that can handle requests.
|
||||||
|
*/
|
||||||
|
export interface RouteHandlerClass {
|
||||||
|
handleRequest(request: Request): RouteHandlerReturnValue
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base type defining a single route handler.
|
* Base type defining a single route handler.
|
||||||
*/
|
*/
|
||||||
export type RouteHandler = (request: Request) => Request | Promise<Request> | ResponseFactory | Promise<ResponseFactory> | void | Promise<void>
|
export type RouteHandler = RouteHandlerFunction | RouteHandlerClass
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base type for a collection of route handlers.
|
* Base type for a collection of route handlers.
|
||||||
@ -49,7 +61,18 @@ export interface RouteDefinition {
|
|||||||
export function isRouteHandler(what: any): what is RouteHandler {
|
export function isRouteHandler(what: any): what is RouteHandler {
|
||||||
return (
|
return (
|
||||||
typeof what === 'function'
|
typeof what === 'function'
|
||||||
|| typeof what.handleRequest === 'function'
|
|| isRouteHandlerClass(what)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the gievn object is a route handling class.
|
||||||
|
* @param what
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
export function isRouteHandlerClass(what: any): what is RouteHandlerClass {
|
||||||
|
return (
|
||||||
|
what && typeof what.handleRequest === 'function' && what.handleRequest.length === 1
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user