Last active
February 27, 2019 12:57
-
-
Save andywer/ffcbb910f19949636109d3cb9856e48d to your computer and use it in GitHub Desktop.
Sample usage - Better HAL package for node
This file contains hidden or 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 Koa from "koa" | |
| import * as KoaHAL from "$new-hal-koa-package" | |
| import { api, Users } from "./hal" | |
| const app = new Koa() | |
| const koaRouter = KoaHAL.Router(api, router => { | |
| // GET /users | |
| router.get(Users, async ctx => { | |
| const users = await queryAllUsers() | |
| ctx.body = Users(users).toObject() | |
| // or just: | |
| // return Users(users) | |
| }) | |
| // ... | |
| }) | |
| app.get("/", ctx => { | |
| ctx.body = { | |
| name: "My Demo API", | |
| _links: api.Links({ | |
| self: "/", | |
| users: api.routeTo(Users) | |
| }) | |
| } | |
| }) | |
| app.use(koaRouter.allowedMethods()) | |
| app.use(koaRouter.routes()) |
This file contains hidden or 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 * as HAL from "$new-hal-package" | |
| interface OrderRecord { | |
| id: string, | |
| items: [], | |
| customer_id: string, | |
| created_at: Date | |
| } | |
| interface UserRecord { | |
| id: string, | |
| name: string, | |
| created_at: Date | |
| } | |
| const router = HAL.Router(routes => { | |
| // Needs to work both ways: Resolve resource instances to paths & define the paths to serve | |
| routes.add(Order, "/orders/:id", order => ({ id: order.id })) | |
| // same as: | |
| routes.add(Order, "/orders/:id") | |
| routes.add(User, "/users/:id") | |
| routes.add(Users, "/users{?limit,offset,total}", (users: Users) => ({ | |
| limit: users.limit, | |
| offset: users.offset, | |
| total: users.total | |
| })) | |
| }) | |
| export const api = HAL.API("https://my-project.com/", router) | |
| export function Order(record: OrderRecord) { | |
| const resource = api.Resource(Order, record) | |
| // same as: | |
| // const resource = HAL.Resource(`/orders/${record.id}`, record) | |
| // or: | |
| // const resource = HAL.Resource(api.routeTo(Order, record), record) | |
| return HAL.addLinks(resource, { | |
| customer: api.routeTo(User, record.customer_id) | |
| }) | |
| } | |
| export function User(record: UserRecord) { | |
| return api.Resource(User, record) | |
| } | |
| export function Users( | |
| records: UserRecord[], | |
| meta: { limit?: number, offset?: number, total?: number } = {}, | |
| links: { prev?: string, next?: string} = {} | |
| ) { | |
| const resource = api.Collection(Users, records, meta) | |
| // same as: | |
| // const resource = HAL.embed(api.Resource(Users, meta), { records }) | |
| return HAL.addLinks(resource, links) | |
| } |
Author
Author
Still need to solve: Resource constructors (User, Users, ...) require api and api requires them...
Shouldn't be hard to solve, though, since api needs references to the resources right away, but the resource constructors use api only when called.
Update: Solution
export function Order(record: OrderRecord) {
const resource = api.Resource(Order, record)
return HAL.addLinks(resource, {
- customer: api.routeTo(User, record.customer_id)
+ customer: HAL.LinkTo(User, record.customer_id)
})
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Alternative Koa HAL routes:
Benefit: Instead of having a source file for routes and one for the HAL resources, we can now also co-locate HAL stuff and route handling per resource (
users.ts,orders.ts, ...)