Skip to content
This repository has been archived by the owner on Sep 8, 2024. It is now read-only.

Commit

Permalink
feat(backend): Route API endpoints
Browse files Browse the repository at this point in the history
Under the `/api`, data can be got by several ways.
  • Loading branch information
5ouma committed Sep 2, 2024
1 parent 23a44c1 commit c6dd5c6
Show file tree
Hide file tree
Showing 5 changed files with 139 additions and 12 deletions.
17 changes: 6 additions & 11 deletions .github/README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,11 @@
# online-2024-e

```sh
# For development
deno task dev
```
## Backend

```sh
# For production
deno task start
```
You can import the API entrypoints and the cocktail type with the following code:

```sh
# For test
deno task test
```ts
import type { API, Cocktail } from "/backend/src/api/mod.ts";
```

For more information, see [the Hono RPC documentation](https://hono.dev/docs/guides/rpc#client).
23 changes: 23 additions & 0 deletions backend/client.http
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
###

GET http://localhost:8000

###

GET http://localhost:8000/api

###

GET http://localhost:8000/api/get?name=アイリッシュコーヒー

###

GET http://localhost:8000/api/get?name=none

###

GET http://localhost:8000/api/get

###

GET http://localhost:8000/api/all
47 changes: 47 additions & 0 deletions backend/src/api/mod.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { assertEquals, assertExists } from "@std/assert";
import { STATUS_CODE } from "@std/http/status";

import { app } from "./mod.ts";

Deno.test("API", async (t: Deno.TestContext) => {
await t.step("GET /", async () => {
const res: Response = await app.request("/");

assertEquals(await res.text(), "Cocktail API");
assertEquals(res.status, STATUS_CODE.OK);
});

await t.step("GET /get", async () => {
const res: Response = await app.request("/get");

assertEquals(await res.json(), {
success: false,
message: "The name query is required",
});
assertEquals(res.status, STATUS_CODE.BadRequest);
});

await t.step("GET /get?name=none", async () => {
const res: Response = await app.request("/get?name=none");

assertEquals(await res.json(), {
success: false,
message: 'The cocktail, "none" not found',
});
assertEquals(res.status, STATUS_CODE.NotFound);
});

await t.step("GET /get?name=アイリッシュコーヒー", async () => {
const res: Response = await app.request("/get?name=アイリッシュコーヒー");

assertExists(await res.json());
assertEquals(res.status, STATUS_CODE.OK);
});

await t.step("/all", async () => {
const res: Response = await app.request("/all");

assertExists(await res.json());
assertEquals(res.status, STATUS_CODE.OK);
});
});
59 changes: 59 additions & 0 deletions backend/src/api/mod.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { type Context, Hono } from "@hono/hono";
export type { Hono };
import { STATUS_CODE } from "@std/http/status";

import { Cocktail } from "./utils/types.ts";
export { Cocktail };
import { cocktails } from "./utils/data.ts";

/**
* The cocktail API
*
* @example Return a response
* ```ts
* const res: Response = await api.request("/");
* ```
* @example Return the requested cocktail detail
* ```ts
* const res: Response = await api.request("/get?name=アイリッシュコーヒー");
* ```
* @example Return an array of all cocktails
* ```ts
* const res: Response = await api.request("/all");
* ```
*/
export const app: Hono = new Hono();

/**
* The cocktail API type
*
* @example
* ```ts
* const client = hc<API>("/");
* ```
*/
export type API = typeof route;

/**
* The cocktail API route
*/
export const route: Hono = app
.get("/", (ctx: Context) => ctx.text("Cocktail API"))
.get("/get", (ctx: Context) => {
const name: string | undefined = ctx.req.query("name");
if (!name) {
return ctx.json(
{ success: false, message: "The name query is required" },
STATUS_CODE.BadRequest,
);
}

const cocktail: Cocktail | undefined = cocktails.find((c: Cocktail) =>
c.name === name
);
return cocktail ? ctx.json({ success: true, data: cocktail }) : ctx.json(
{ success: false, message: `The cocktail, "${name}" not found` },
STATUS_CODE.NotFound,
);
})
.get("/all", (ctx: Context) => ctx.json(cocktails));
5 changes: 4 additions & 1 deletion backend/src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { type Context, Hono } from "@hono/hono";
export type { Hono };
import { logger } from "@hono/hono/logger";

import { app as api } from "./api/mod.ts";

/**
* The Hono application for this project.
*
Expand All @@ -13,6 +15,7 @@ import { logger } from "@hono/hono/logger";
export const app: Hono = new Hono();
app.use(logger());
app
.get("/", (ctx: Context) => ctx.text("Hello, World!"));
.get("/", (ctx: Context) => ctx.text("Hello, World!"))
.route("/api", api);

Deno.serve(app.fetch);

0 comments on commit c6dd5c6

Please sign in to comment.