Created
January 24, 2024 18:13
-
-
Save kwhinnery/4e7ddf4aee7fd8262acadee3620131af to your computer and use it in GitHub Desktop.
Example code from today's decorators presentation! Uses the older Stage 2 decorators API - look for the Stage 3 decorators API to release in Deno 1.40.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// deno-lint-ignore-file no-explicit-any | |
import { Hono } from "https://deno.land/x/[email protected]/mod.ts"; | |
import { Context } from "https://deno.land/x/[email protected]/context.ts"; | |
import * as dejs from "https://deno.land/x/[email protected]/mod.ts"; | |
// Initialize class routes by instantiating a version of them | |
export function register(...args: any) { | |
args.forEach((C: any) => { | |
console.log("Mounting routes for", C.name); | |
new C(); | |
}); | |
} | |
// Create a single, module-scoped Hono application | |
export const app = new Hono(); | |
export function route(path = "/", method = "get"): any { | |
return function (proto: any, _methodName: any, context: any): any { | |
// Register a route that calls the given method. | |
app.all(path, async (c, next) => { | |
if (c.req.method.toLowerCase() !== method.toLowerCase()) { | |
return next(); | |
} | |
// Call original function | |
const originalValue = await context.value.call(proto, c); | |
// Render JSON or HTML body | |
if (typeof originalValue === "string") { | |
return c.html(originalValue); | |
} else { | |
return c.json(originalValue); | |
} | |
}); | |
// Pass back wrapped function (unchanged) | |
return { | |
value: context.value, | |
}; | |
}; | |
} | |
export function template(templateName: string): any { | |
return function ( | |
proto: any, | |
_methodName: any, | |
context: any, | |
): any { | |
async function wrapped(c: Context): Promise<any> { | |
const originalValue = await context.value.call(proto, c); | |
return dejs.renderFileToString(templateName, { | |
data: originalValue, | |
}); | |
} | |
// Pass back wrapped function | |
return { | |
value: wrapped, | |
}; | |
}; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<h1>Todos</h1> | |
<ul> | |
<% data.forEach(val => { %> | |
<li><%= val.value.todo %></li> | |
<% }); %> | |
</ul> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { app, register } from "./hono_decorators.ts"; | |
import { TodoResource } from "./todo.ts"; | |
// Register route handlers through static initialization | |
register(TodoResource); | |
// Mount Hono app to serve incoming requests | |
Deno.serve(app.fetch); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Context } from "https://deno.land/x/[email protected]/context.ts"; | |
import { route, template } from "./hono_decorators.ts"; | |
// Create a persistent KV database | |
const kv = await Deno.openKv(); | |
export class TodoResource { | |
@route("/todos", "GET") | |
@template("list.ejs") | |
async listTodos() { | |
const iter = await kv.list({ prefix: ["todos"] }); | |
const todos = []; | |
for await (const res of iter) todos.push(res); | |
return todos; | |
} | |
@route("/todos", "POST") | |
async createTodo(c: Context) { | |
const { todo, done } = await c.req.json(); | |
const id = crypto.randomUUID(); | |
return await kv.set(["todos", id], { id, todo, done }); | |
} | |
@route("/todos/:id", "GET") | |
async getTodo(c: Context) { | |
const id = c.req.param("id"); | |
return await kv.get(["todos", id]); | |
} | |
@route("/todos/:id", "POST") | |
async updateTodo(c: Context) { | |
const id = c.req.param("id"); | |
const { todo, done } = await c.req.json(); | |
return await kv.set(["todos", id], { id, todo, done }); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment