Honoを使って爆速でAPIを作成🔥

# Honoって何？
Honoは、Cloudflare Workers上で動かすことを目的に作られた軽量なWebフレームワークです。Honoは、WebスタンダードAPIのみを利用しており、Webアプリケーションを構築するためのランタイムとして利用しています。また、ファーストクラスでTypeScriptをサポートしており、エッジコンピューティング環境に適したWebフレームワークとして注目されています。さらに、HonoとViteを組み合わせた、HonoXというメタフレームワークも公開されています。

# ドキュメントはこちら
日本語版と英語版の両方があるのはいいっすね

英語版

https://hono.dev/

日本語版

https://hono-ja.pages.dev/

HonoX

https://github.com/honojs/honox

# Start
以下のコマンドを実行していきます。

```
npm create hono@latest
```
コマンドを実行すると、以下のように質問されるので、答えていきます。

・ディレクトリ名を設定(今回は「hono-demo」と設定)
```
? target derectory {ディレクトリ名}
```

・テンプレートを指定する。今回は、「cloudflare-workers」を指定。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2613586/bebaca59-f996-0b2c-c398-cc9486cb9abe.png)

・  「yes」を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2613586/9bc01b46-e985-d89a-bd85-2572775bae13.png)

・ パッケージ管理ツールを選択する。今回は、「npm」を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2613586/a8b11680-6e23-f266-505f-c60f417ccc17.png)

・プロジェクトが自動で作成される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2613586/fae8be73-ba4f-543e-e373-0a1381eafa86.png)

・ **wrangler**をインストールする。
**wrangler**は、Cloudflare Workersの管理とデプロイに使用されるコマンドラインツールです。

```
cd hono-demo
npm -i -g wrangler
```

・ローカルサーバーを起動
以下のコマンドでローカルサーバーを起動してみます。
```
npm run dev
```

以下のように表示されれば、サーバーが起動しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2613586/f8e461d2-3a9d-0b26-be2a-e3e6ba0b3859.png)

ブラウザを開き、「http://127.0.0.1:8787」にアクセスしてみましょう。
以下のようにレスポンスが返ってくれば、成功です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2613586/557ba336-f619-cdb6-1d41-7ae9ce57572f.png)


# 簡単なAPIを作成
それぞれのHTTPメソッドのサンプルコードを記載しておきます。
参考にしてください。

## GET

特定の記事を取得するAPI
``` index.ts
import { Hono } from "hono";
import { prettyJSON } from "hono/pretty-json";

let blogPosts = [
  {
    id: "1",
    title: "blog1",
    content: "content1"
  },
  {
    id: "2",
    title: "blog2",
    content: "content2"
  },
  {
    id: "3",
    title: "blog3",
    content: "content3"
  }
]

const app = new Hono();
app.use("*", prettyJSON());

app.get("/", (c) => {
  return c.text("Hello Hono!");
});

app.get("/entry/:id", (c) => {
  const id = c.req.param("id");
  return c.json({
    "you id is": id,
  });
});

```
## POST
記事を追加するAPI

``` index.ts
import { Hono } from "hono";
import { prettyJSON } from "hono/pretty-json";

let blogPosts = [
  {
    id: "1",
    title: "blog1",
    content: "content1"
  },
  {
    id: "2",
    title: "blog2",
    content: "content2"
  },
  {
    id: "3",
    title: "blog3",
    content: "content3"
  }
]

const app = new Hono();
app.use("*", prettyJSON());

app.post("/post", async (c) => {
  const { title, content } = await c.req.json<{
    title: string;
    content: string
  }>();

  const newPost = {id: String(blogPosts.length + 1), title, content};
  blogPosts = [...blogPosts, newPost];
})
```
## PUT

記事を編集するAPI

``` index.ts
import { Hono } from "hono";
import { prettyJSON } from "hono/pretty-json";

let blogPosts = [
  {
    id: "1",
    title: "blog1",
    content: "content1"
  },
  {
    id: "2",
    title: "blog2",
    content: "content2"
  },
  {
    id: "3",
    title: "blog3",
    content: "content3"
  }
]

app.put('/post/:id', async (c) => {
  const id = c.req.param("id");
  const index = blogPosts.findIndex((p) => p.id === id);

  if(index === -1){
    return c.json({message: "Post not found"}, 400);
  }

  const {title, content} = await c.req.json();

  blogPosts[index] = { ...blogPosts[index], title, content };

  return c.json(blogPosts[index]);
})
```
## DELETE
記事を削除するAPI
``` index.ts
import { Hono } from "hono";
import { prettyJSON } from "hono/pretty-json";

let blogPosts = [
  {
    id: "1",
    title: "blog1",
    content: "content1"
  },
  {
    id: "2",
    title: "blog2",
    content: "content2"
  },
  {
    id: "3",
    title: "blog3",
    content: "content3"
  }
]

app.delete('/post/:id', (c) => {
  const id = c.req.param("id");
  const index = blogPosts.findIndex((p) => p.id === id);

  if(index === -1){
    return c.json({message: "Post not found"}, 400);
  }

  const deletedPost = blogPosts[index];
  blogPosts = blogPosts.filter((p) => p.id !== id);

  return c.json({message: "Post deleted", post: deletedPost});
})
```


# 最後に
他にも色々な記事を書いているので、よければ読んでいってください！

https://qiita.com/hukuryo/items/97797a91d7e2ee0bcabc

https://qiita.com/hukuryo/items/2c07c52ff3386d5d75b9

https://qiita.com/hukuryo/items/ebeb26823f944f143b11