🔥
HonoのHCで外部APIのAPIクライアントを作る
Honoのhcを用いて、このようなAPIクライアントを型定義から生成しようという試み。
詳しくはこの記事を読む。 https://zenn.dev/yusukebe/articles/a00721f8b3b92e
これはHackerNewsのAPIのサンプルコード。
const client = hc<Api>("https://hacker-news.firebaseio.com")
const resp = await client.v0.item[":item"].$get({
param: { item: "8863.json" },
query: { print: "pretty" },
})
const json = await resp.json()
console.log(json)
このようにhcのジェネリクスにリクエストに関する情報を渡すことで型を定義している。
import type { Hono } from "hono"
import { hc } from "hono/client"
import type { BlankEnv } from "hono/types"
import type { StatusCode } from "hono/utils/http-status"
type Api = Hono<
BlankEnv,
{
"/v0/item/:item": {
$get: {
input: {
param: {
item: string
}
query: {
print?: "pretty"
}
}
output: {
type: "story" | "comment" | "job" | "poll" | "pollopt"
}
outputFormat: "json"
status: StatusCode
}
}
}
>
const client = hc<Api>("https://hacker-news.firebaseio.com")
基本的にパス、メソッド($get)、リクエスト内容の順に書いていくのみ。
"/v0/item/:item": {
$get: {
input: {}
output: {}
}
$post: {
input: {}
output: {}
}
}
このinputには他にも「param」「query」「form」などが渡せる。
何が嬉しいか
WorkersでHonoxでライブラリを使う際にViteのESMとNode.jsやらで問題が度々発生する。例えばGoogleのライブラリはNode.jsに依存していたりする。
簡易的なライブラリを作る
スプレッドシートなど共有ドライブのファイルを取得するには以下のエンドポイントが使える。
ここでドキュメントのパスとクエリパラメーターとリクエスト本文を用いて型を定義できる。
import type { BlankEnv } from "hono/types"
import type { Hono } from "hono"
import type { StatusCode } from "hono/utils/http-status"
import type { drive_v3 } from "@googleapis/drive"
export type GoogleapisWww = Hono<
BlankEnv,
{
"/drive/v3/files": {
$get: {
input: {
query: {
q?: string
pageSize?: string
fields?: string
orderBy?: string
}
}
output: {
json: drive_v3.Schema$FileList
}
outputFormat: "json"
status: StatusCode
}
}
}
>
返り値のJSONの型はライブラリから取得できる。
import type { drive_v3 } from "@googleapis/drive"
このようにhcの引数にURLを渡して1つのオブジェクトにして管理している。
import { hc } from "hono/client"
import type { GoogleapisWww } from "~/lib/google/googleapis-www"
import type { GoogleapisOauth2 } from "~/lib/google/googleapis-oauth2"
import type { GoogleapisSheets } from "~/lib/google/googleapis-sheets"
export const googleapis = {
/**
* https://www.googleapis.com
*/
www: hc<GoogleapisWww>("https://www.googleapis.com"),
/**
* https://oauth2.googleapis.com
*/
oauth2: hc<GoogleapisOauth2>("https://oauth2.googleapis.com"),
/**
* https://sheets.googleapis.com
*/
sheets: hc<GoogleapisSheets>("https://sheets.googleapis.com"),
}
このような感じで使えるはず。
const resp = await googleapis.www.drive.drive.v3.files.$get()
Discussion