Meal API: Elysia backend serving the menu API and a single-file frontend
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
import { Elysia, status } from 'elysia'
|
||||
import { readFileSync } from 'node:fs'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
|
||||
const PORT = process.env.PORT || 3000
|
||||
|
||||
// Resolve index.html next to this file, so it works no matter where you run it from.
|
||||
const INDEX_HTML = readFileSync(fileURLToPath(new URL('./index.html', import.meta.url)), 'utf8')
|
||||
|
||||
const HTML_HEADERS = {
|
||||
'content-type': 'text/html; charset=utf-8',
|
||||
'content-length': String(Buffer.byteLength(INDEX_HTML)),
|
||||
}
|
||||
|
||||
// The food menu data.
|
||||
const menu = [
|
||||
{ id: 1, food: 'Adobo', price: 75 },
|
||||
{ id: 2, food: 'Fried Chicken', price: 50 },
|
||||
{ id: 3, food: 'Yum Burger', price: 70 },
|
||||
]
|
||||
|
||||
// Elysia serves through Bun.serve on Bun, but it needs the Node adapter on Node.
|
||||
// This one file therefore runs on either runtime: `bun server.js` or `node server.js`.
|
||||
const adapter =
|
||||
typeof Bun === 'undefined' ? (await import('@elysiajs/node')).node() : undefined
|
||||
|
||||
new Elysia(adapter ? { adapter } : {})
|
||||
.onRequest(({ request }) => {
|
||||
if (request.method !== 'GET') {
|
||||
return status(405, { error: 'Method not allowed' })
|
||||
}
|
||||
})
|
||||
|
||||
// GET /api/menu -> the whole menu
|
||||
.get('/api/menu', () => menu)
|
||||
|
||||
// GET /api/menu/:id -> one item
|
||||
.get('/api/menu/:id', ({ params: { id }, status }) => {
|
||||
const num = Number(id)
|
||||
|
||||
if (!Number.isInteger(num) || num < 1) {
|
||||
return status(400, { error: 'ID must be a whole number, like 1.' })
|
||||
}
|
||||
|
||||
const item = menu.find((food) => food.id === num)
|
||||
if (!item) {
|
||||
return status(404, { error: `No menu item with ID ${num}.` })
|
||||
}
|
||||
|
||||
return item
|
||||
})
|
||||
|
||||
// GET / -> the frontend
|
||||
.get('/', () => new Response(INDEX_HTML, { headers: HTML_HEADERS }))
|
||||
.get('/index.html', () => new Response(INDEX_HTML, { headers: HTML_HEADERS }))
|
||||
|
||||
.get('*', () => status(404, 'Not found'))
|
||||
|
||||
.listen(PORT)
|
||||
|
||||
const runtime = typeof Bun === 'undefined' ? 'Node.js' : 'Bun'
|
||||
console.log(`Meal API running at http://localhost:${PORT} (${runtime})`)
|
||||
Reference in New Issue
Block a user