@moneypot/hub
' is first and foremost a GraphQL server that a exposes GET /graphql
and POST /graphql
REST routes.
However, you may want to add additional REST routes. e.g. GET /health
or GET /metrics
.
You can access the underlying Express
instance with configureApp(app: Express) => void
.
import { ServerOptions, startAndListen } from "@moneypot/hub"; import { Express, CaasRequest, Response, NextFunction, } from "@moneypot/hub/express"; const options: ServerOptions = { configureApp(app: Express) { app.use((req: CaasRequest, res: Response, next: NextFunction) => { switch (req.identity?.kind) { case "user": console.log("Logged in as user", req.identity.user.uname); break; case "operator": console.log("Logged in as operator"); break; default: console.log("Unauthenticated request"); break; } next(); }); app.get("/health", (req: CaasRequest, res: Response) => { res.json({ status: "healthy" }); }); }, // ... }; startAndListen(options, ({ port }) => { console.log(`Listening on port ${port}`); });
You can access the user info from the request object: req.identity
.
It represents three states:
Authorization: "session:{sessionToken}"
was valid)Authorization: "apikey:{apiKey}"
was valid)The shape of req.identity
is:
export interface CaasRequest extends Request { identity?: | { kind: "user"; user: DbUser; sessionId: string; } | { kind: "operator"; apiKey: string }; }
So, you could use it like this to restrict route access to logged-in users:
import { Express, CaasRequest, Response, NextFunction, } from "@moneypot/hub/express"; import { DbUser } from "@moneypot/hub/db"; import * as database from "./database"; app.get("/bets", (req: CaasRequest, res: Response, next: NextFunction) => { if (req.identity?.kind !== "user") { return res.status(401).send("Unauthorized"); } const user: DbUser = req.identity.user; const bets = await database.listBetsForUserId(user.id); res.json(bets); });
And here's how you can use it for a route that is limited to operator api keys:
app.get("/metrics", (req: CaasRequest, res: Response, next: NextFunction) => { if (req.identity?.kind !== "operator") { return res.status(401).send("Unauthorized"); } res.json({ metrics: "TODO" }); });