Honoを触ってみる

こんにちは、しおです。
最近HonoというWebフレームワークのことを知りましたので、
触ってみた内容をまとめていこうとおもいます。
Honoについて
HonoはWeb標準に基づいて実装されているフレームワークで、またTypeScriptで開発されているとのことです。
また、高速な動作にも期待ができるようです。
公式のドキュメントにも記載がありますが、TypeScriptで開発されているため、
ランタイムとしてTypeScriptをそのまま実行できるBunとの相性が良さそうかなと思いました。
Honoのドキュメントはこちらです
https://hono.dev/docs/
早速サーバーをたてる
それでは早速サーバーをたてるところから
自分は元々bunを使ってましたので、今回もbunを使っていきます。
まずはフレームワークの追加です。
bun add hono
そしたらHello, World! からですね。
index.tsを変更していきます。
import { Hono } from "hono";
const app = new Hono();
app.get("/", (c) => c.text("Hello World!"));
export default app;
index.tsを走らせたら完了です。
簡単ですね!
bun run index.ts
localhost:3000でローカルサーバーが起動するはずです。
色々なレスポンスを返してみる
もうサーバーがたったので、
ソースを変更しながら、どんなことができるのかを試していこうと思います。
JSONを返す
エンドポイントを追加してJSONを返してみようと思います。
app.get("/json", (c) =>
c.json({
message: "Hello, World!",
})
);
エンドポイントの追加は、Express.jsと同じようなインターフェースで追加できます。
Expressとの違いはリクエストごとにコンテキスト変数が1つ渡されるところでしょうか。
コンテキストについて
引数c
として受け取っているのは、Honoから提供されるContextオブジェクトです。
ここからリクエストの情報であったり、レスポンスヘッダーの設定などをすることが可能です。
参考:
https://hono.dev/docs/api/context
htmlを返す
さて、コンテキストについてもざっくりと理解したところで、
今度はhtmlを返してみます。
なんとHonoではJSXを使ってレスポンスもできるんです。
JSXを利用するためにindex.tsを.tsxに変更して、
tsconfig.jsonをいじります。
"compilerOptions": {
...
"jsx": "react-jsx",
"jsxImportSource": "hono/jsx",
...
}
そしてindex.tsxにhtmlのレスポンスを追加します。
const View = () => {
return (
<html>
<body>
<h1>Hello World!</h1>
</body>
</html>
);
};
app.get("/html-page", (c) => {
return c.html(<View />);
});
これで/html-page
へリクエストするとhtmlで返ってくるようになりました。
リクエストの情報を使う
今度はgetではなくpostを想定して、リクエストされたデータを使ってみようと思います。
今回は簡単にリクエストされた情報をそのまま返すようにしてみます。
パスパラメータなどもコンテキストから取得することができます。
リクエストはapplication/json
で受けることを想定しています。
app.post("/post/:param", async (c) => {
return c.json({
path_param: c.req.param("param"),
request_body: await c.req.json(),
});
});
curlなどでpostしてみるとリクエストの情報が利用できていることがわかるはずです。
curl http://localhost:3000/post/test -d '{"message": "hello"}' -H "Content-Type: application/json"
/// レスポンスは整形しています
{
"path_param": "test",
"request_body": {
"message": "hello"
}
}
ヘッダーをいじる
レスポンスヘッダーも簡単にいじることができます。
カスタムヘッダーを何か追加してみましょう。
app.get("/custom-header", (c) => {
c.header("Sample-Custom-Header", "custom-header");
return c.body("Response with custom header.");
});
こちらもcurlやブラウザのDevツールなどで確認するとヘッダーが返ってくることがわかると思います。
curl http://localhost:3000/custom-header -i
HTTP/1.1 200 OK
sample-custom-header: custom-header
content-type: text/plain;charset=utf-8
...
Response with custom header.
ヘルパー
Honoでは開発に便利なヘルパーも提供されていて、
例えばCookieを扱うためのヘルパーがあります。
参考: https://hono.dev/docs/helpers/cookie
import { deleteCookie, setCookie } from "hono/cookie";
app.get("/set-cookie", (c) => {
setCookie(c, "sample-cookie", "chocolate-cookie");
return c.body("set cookie.");
});
app.get("/delete-cookie", (c) => {
deleteCookie(c, "sample-cookie");
return c.body("delete cookie.");
});
これで該当のパスへのアクセスでCookieが保存されることがわかるかと思います。
ミドルウェア
ミドルウェアについても多くのものが提供されています。
わかりやすいのはロガーでしょうか。
参考: https://hono.dev/docs/middleware/builtin/logger
インポートして、ミドルウェアを利用するに宣言すればリクエストに合わせてログが出力されるようになるはずです。
import { logger } from "hono/logger";
app.use(logger());
ヘルパーやミドルウェアについては他にも多くのものがあるので、ぜひドキュメントをご覧ください。
書ききれないこと
ここまでで基本的な部分については書けたかと思います。
とはいえ、まだまだ書ききれないことがあります、ルーティングやバリデーションなどなど
より深い部分についても機会があったら書いていこうと思います。