-
Notifications
You must be signed in to change notification settings - Fork 0
API Design
mtkdv edited this page May 17, 2023
·
3 revisions
API 設計全般に関して、以下の記事を参考にしました。
Developers.IO 2018 で「API 設計」の話をしてきた #cmdevio2018 | DevelopersIO
記事内で紹介されている API アクションという概念を取り入れ、以下のように設計しました。
action | method | path |
---|---|---|
GetProfile | GET | /users/[userId]/profile |
GetProfileBaseInfo | GET | /users/[userId]/profile/_baseInfo |
GetProfilePublished | GET | /users/[userId]/profile/_published |
PatchProfileBaseInfo | PATCH | /users/[userId]/profile/_baseInfo |
PatchProfilePublished | PATCH | /users/[userId]/profile/_published |
GetCustom | GET | /users/[userId]/custom |
PatchCustom | PATCH | /users/[userId]/custom |
ListUserLink | GET | /users/[userId]/links |
ListUserCategory | GET | /users/[userId]/categories |
ListUserVideo | GET | /users/[userId]/videos |
UpsertUserVideo | PUT | /users/[userId]/videos |
QueryProfile | GET | /query/profiles?slug=hoge |
QueryPublicResources | GET | /query/public-resources?slug=hoge |
「リソース表現が異なる」とは、同一のリソースであっても、SELECT に指定するカラムなどにより出力結果が異なることを指します。
ユースケースごとにリソース表現が異なる場合にも API アクションを切り、_
から始まるセグメントを追加してエンドポイントも分離するようにしています。
表中のGetProfileBaseInfo
とGetProfilePublished
では、取得するカラムがそれぞれ異なります。
クエリパラメータにfields
を渡してエンドポイントを共通化せずに、リソース表現ごとにエンドポイントを分けるようにした理由は、主に以下の 2 点。
- 共通化しているエンドポイントのコードを変更した際に、他のリクエスト元への影響を考慮しなくてもいい
- 「API リクエストの HTTP メソッドとパスが決まれば、API アクションが決まる」という、わかりやすさを重視した設計指針を尊重
HTTP メソッドとエンドポイントを一語で表せる API アクション名は、プロジェクト内での共通用語としてはもちろん、コード内でも有効に活用できます。
今回は以下の用途で API アクション名を利用しています。
- データのキャッシュ管理に使用される
queryKey
-
useQuery
,useMutation
をラップしたカスタムフック名
export const useGetProfile = () => {
const userId = useUserId();
return useQuery<Profile, AxiosError>({
queryKey: queryKeys.getProfile,
queryFn: async () => {
const res = await axios.get<Profile>(`/api/users/${userId}/profile`);
return res.data;
},
enabled: !!userId,
useErrorBoundary: true,
});
};