Separate route definitions and where they're served from
This commit is contained in:
45
deno/app.ts
Normal file
45
deno/app.ts
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
// app.ts
|
||||||
|
|
||||||
|
import { services } from "./services";
|
||||||
|
import{DenoRequest, Method, ProcessedRoute, Request, Route} from './types'
|
||||||
|
|
||||||
|
import {routes} from './routes'
|
||||||
|
|
||||||
|
services.logging.log({ foo: 1 });
|
||||||
|
const processedRoutes: ProcessedRoute[] = routes.map(
|
||||||
|
(route: Route, idx: number, allRoutes: Route[]) => {
|
||||||
|
const pattern: URLPattern = new URLPattern({ pathname: route.path });
|
||||||
|
const method: Method = route.method;
|
||||||
|
const handler = async (denoRequest: DenoRequest) => {
|
||||||
|
const req: Request = {
|
||||||
|
pattern: route.pattern,
|
||||||
|
path: denoRequest.path,
|
||||||
|
method: denoRequest.method,
|
||||||
|
parameters: { one: 1, two: 2 },
|
||||||
|
denoRequest,
|
||||||
|
};
|
||||||
|
return route.handler(req);
|
||||||
|
};
|
||||||
|
|
||||||
|
const retval: ProcessedRoute = { pattern, method, handler };
|
||||||
|
|
||||||
|
return retval
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
async function handler(req: globalThis.Request): globalThis.Response {
|
||||||
|
for (const [idx, pr] of processedRoutes.entries()) {
|
||||||
|
const match = pr.pattern.exec(req.url);
|
||||||
|
if (match) {
|
||||||
|
const resp = await pr.handler(req);
|
||||||
|
|
||||||
|
return new globalThis.Response(resp.result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new globalThis.Response("not found", { status: 404 });
|
||||||
|
}
|
||||||
|
|
||||||
|
Deno.serve(handler);
|
||||||
|
|
||||||
104
deno/routes.ts
104
deno/routes.ts
@@ -1,18 +1,16 @@
|
|||||||
type Method = "get" | "post" | "put" | "patch" | "delete";
|
/// <reference lib="dom" />
|
||||||
|
|
||||||
|
import { sleep } from "https://deno.land/x/sleep/mod.ts";
|
||||||
|
|
||||||
import { HttpCode, httpCodes } from "./http-codes.ts";
|
import { HttpCode, httpCodes } from "./http-codes.ts";
|
||||||
import { ContentType, contentTypes } from "./content-types";
|
import { ContentType, contentTypes } from "./content-types";
|
||||||
import { services } from "./services";
|
import { services } from "./services";
|
||||||
|
import {DenoRequest, Handler, Response, Method, UserRequest, Request, Route, ProcessedRoute } from './types.ts'
|
||||||
|
|
||||||
type Response = {
|
|
||||||
code: HttpCode;
|
|
||||||
contentType: ContentType;
|
|
||||||
result: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
type Handler = (req: Request) => Response;
|
|
||||||
|
|
||||||
const phandler: Handler = (req: Request) => {
|
|
||||||
|
const phandler: Handler = async (req: Request) => {
|
||||||
const code = httpCodes.success.OK;
|
const code = httpCodes.success.OK;
|
||||||
return {
|
return {
|
||||||
code,
|
code,
|
||||||
@@ -21,17 +19,54 @@ const phandler: Handler = (req: Request) => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
type Route = {
|
|
||||||
path: string;
|
|
||||||
methods: Method[];
|
// FIXME: Obviously put this somewhere else
|
||||||
handler: Handler;
|
const okText = (out: string) => {
|
||||||
|
const code = httpCodes.success.OK;
|
||||||
|
|
||||||
|
return {
|
||||||
|
code,
|
||||||
|
result: out,
|
||||||
|
contentType: contentTypes.text.plain,
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const routes: Route[] = [
|
const routes: Route[] = [
|
||||||
|
{
|
||||||
|
path: "/slow",
|
||||||
|
methods: ["get"],
|
||||||
|
handler: async (_req) => {
|
||||||
|
console.log("starting slow request") ;
|
||||||
|
await sleep(10);
|
||||||
|
console.log("finishing slow request"); return okText("that was slow");
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/list",
|
||||||
|
methods: ["get"],
|
||||||
|
handler: async (_req) => {
|
||||||
|
const code = httpCodes.success.OK;
|
||||||
|
const lr = (rr: Route[]) => {
|
||||||
|
const ret = rr.map((r: Route) => {
|
||||||
|
return r.path;
|
||||||
|
});
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
|
||||||
|
const listing = lr(routes).join(", ");
|
||||||
|
return {
|
||||||
|
code,
|
||||||
|
result: listing + "\n",
|
||||||
|
contentType: contentTypes.text.plain,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: "/ok",
|
path: "/ok",
|
||||||
methods: ["get"],
|
methods: ["get"],
|
||||||
handler: (req) => {
|
handler: async (_req) => {
|
||||||
const code = httpCodes.success.OK;
|
const code = httpCodes.success.OK;
|
||||||
const rn = services.random.randomNumber();
|
const rn = services.random.randomNumber();
|
||||||
|
|
||||||
@@ -45,7 +80,7 @@ const routes: Route[] = [
|
|||||||
{
|
{
|
||||||
path: "/alsook",
|
path: "/alsook",
|
||||||
methods: ["get"],
|
methods: ["get"],
|
||||||
handler: (req) => {
|
handler: async (_req) => {
|
||||||
const code = httpCodes.success.OK;
|
const code = httpCodes.success.OK;
|
||||||
return {
|
return {
|
||||||
code,
|
code,
|
||||||
@@ -56,46 +91,11 @@ const routes: Route[] = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
type DenoRequest = globalThis.Request;
|
|
||||||
type UserRequest = {};
|
|
||||||
type Request = {
|
|
||||||
pattern: string;
|
|
||||||
path: string;
|
|
||||||
method: Method;
|
|
||||||
parameters: object;
|
|
||||||
denoRequest: globalThis.Request;
|
|
||||||
};
|
|
||||||
type ProcessedRoute = { pattern: URLPattern; method: Method; handler: Handler };
|
|
||||||
const processedRoutes: ProcessedRoute[] = routes.map(
|
|
||||||
(route: Route, idx: number, allRoutes: Route[]) => {
|
|
||||||
const pattern: URLPattern = new URLPattern({ pathname: route.path });
|
|
||||||
const method: Method = route.method;
|
|
||||||
const handler = (denoRequest: DenoRequest) => {
|
|
||||||
const req: Request = {
|
|
||||||
pattern: route.pattern,
|
|
||||||
path: denoRequest.path,
|
|
||||||
method: denoRequest.method,
|
|
||||||
parameters: { one: 1, two: 2 },
|
|
||||||
denoRequest,
|
|
||||||
};
|
|
||||||
return route.handler(req);
|
|
||||||
};
|
|
||||||
|
|
||||||
return { pattern, method, handler };
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
function handler(req: globalThis.Request): globalThis.Response {
|
|
||||||
for (const [idx, pr] of processedRoutes.entries()) {
|
|
||||||
const match = pr.pattern.exec(req.url);
|
|
||||||
if (match) {
|
|
||||||
const resp = pr.handler(req);
|
|
||||||
|
|
||||||
return new globalThis.Response(resp.result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return new globalThis.Response("not found", { status: 404 });
|
|
||||||
}
|
|
||||||
|
|
||||||
Deno.serve(handler);
|
|
||||||
|
|
||||||
|
export {routes}
|
||||||
|
|||||||
@@ -6,6 +6,6 @@ DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
|||||||
|
|
||||||
cd "$DIR"
|
cd "$DIR"
|
||||||
|
|
||||||
deno run --allow-net --unstable-sloppy-imports --watch routes.ts
|
deno run --allow-net --unstable-sloppy-imports --watch app.ts
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
40
deno/types.ts
Normal file
40
deno/types.ts
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
// types.ts
|
||||||
|
|
||||||
|
// FIXME: split this up into types used by app developers and types internal
|
||||||
|
// to the framework.
|
||||||
|
|
||||||
|
|
||||||
|
import { HttpCode, httpCodes } from "./http-codes.ts";
|
||||||
|
import { ContentType, contentTypes } from "./content-types";
|
||||||
|
|
||||||
|
|
||||||
|
export type Method = "get" | "post" | "put" | "patch" | "delete";
|
||||||
|
|
||||||
|
|
||||||
|
export type DenoRequest = globalThis.Request;
|
||||||
|
export type UserRequest = {};
|
||||||
|
export type Request = {
|
||||||
|
pattern: string;
|
||||||
|
path: string;
|
||||||
|
method: Method;
|
||||||
|
parameters: object;
|
||||||
|
denoRequest: globalThis.Request;
|
||||||
|
};
|
||||||
|
export type ProcessedRoute = { pattern: URLPattern; method: Method; handler: Handler };
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export type Response = {
|
||||||
|
code: HttpCode;
|
||||||
|
contentType: ContentType;
|
||||||
|
result: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type Handler = (req: Request) => Promise<Response>;
|
||||||
|
|
||||||
|
export type Route = {
|
||||||
|
path: string;
|
||||||
|
methods: Method[];
|
||||||
|
handler: Handler;
|
||||||
|
interruptable?: boolean
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user