私はRESTの初心者であり、いくつかのRESTfulなサービスではそれらがupdate/get/deleteとCreateのために異なるリソースURIを使うことを観察しました。といった
私はこのURIの命名規則について少し混乱しています。リソースの作成には、何を使うべきですか。それを決定する際の基準は何ですか?
/resources
を使用する前提は、「すべての」リソースを表しているということです。 GET /resources
を実行すると、コレクション全体が返される可能性があります。 /resources
にPOSTすることで、コレクションに追加しています。
ただし、個々のリソースは/ resourceにあります。 GET /resource
を実行した場合、この要求は意味をなさないのでエラーになる可能性がありますが、/resource/123
は完全に意味があります。
/resource
の代わりに/resources
を使用するのは、たとえばファイルシステムとファイルの集まりで作業する場合の方法と似ており、/resource
は個々の123
、456
ファイルを含む「ディレクトリ」です。
どちらの方法も正しいか間違っている、あなたが一番好きなもので行きなさい。
私にとっては、コードを直接コード化できる(自動化しやすい)スキーマを持つほうがよいでしょう。これは主に、コードが両端に存在することになるからです。
GET /orders <---> orders
POST /orders <---> orders.Push(data)
GET /orders/1 <---> orders[1]
PUT /orders/1 <---> orders[1] = data
GET /orders/1/lines <---> orders[1].lines
POST /orders/1/lines <---> orders[1].lines.Push(data)
私はこれをすることの意味も見ません、そして、私はそれが最良のURIデザインではないと思います。 RESTfulサービスのユーザーとして、私はリストにアクセスするかリスト内の特定のリソースにアクセスするかにかかわらず、リストリソースは同じ名前を持つことを期待します。リストリソースを使用するか特定のリソースを使用するかにかかわらず、同じ識別子を使用する必要があります。
複数形
orders/
は注文のインデックスリストを取得します。次に例を示します。
GET /resources
- リソース項目のリストを返します
POST /resources
- 1つ以上のリソース項目を作成します
PUT /resources
- 1つ以上のリソース項目を更新します
PATCH /resources
- 1つ以上のリソース項目を部分的に更新します
DELETE /resources
- すべてのリソース項目を削除します
そして単一のリソース項目の場合:
GET /resources/:id
- :id
パラメータに基づいて特定のリソース項目を返します
POST /resources/:id
- 指定されたIDを持つリソース項目を1つ作成します(検証が必要です)
PUT /resources/:id
- 特定のリソース項目を更新します
PATCH /resources/:id
- 特定のリソース項目を部分的に更新します
DELETE /resources/:id
- 特定のリソース項目を削除します
単数形の支持者には、このように考えてください。誰かにorder
を依頼して、1つのこと、または物のリストを期待しますか。それで、あなたが/order
をタイプするとき、なぜあなたはサービスがもののリストを返すと期待するでしょうか?
便利さ物事は不規則な複数の名前を持つことができます。時々彼らはそれを持っていません。しかし、単数形の名前は常にあります。
例えばCustomerAddressを超えるCustomerAddress
この関連リソースを検討してください。
この/order/12/orderdetail/12
は/orders/12/orderdetails/4
より読みやすく論理的です。
リソースはデータベーステーブルのようなエンティティを表します。それは論理的な特異名を持つべきです。これが answer overテーブル名です。
クラスは常に単数形です。 ORMツールはクラス名と同じ名前のテーブルを生成します。ますます多くのツールが使用されているので、単数形の名前が標準になりつつあります。
最も一般的な方法は、複数形が使用されるRESTful APIです。 /api/resources/123
、私が複数の名前よりも単数の名前の使用がより適切/表現的であると感じる特別な場合があります。それは一対一の関係の場合です。具体的には、ターゲット項目が値オブジェクトであるかどうか(ドメイン駆動設計パラダイム)。
すべてのリソースが1対1のaccessLog
を持っていると仮定しましょう。それは/api/resources/123/accessLog
として表すことができます。通常の動詞(POST、PUT、DELETE、GET)は意図を適切に表現し、関係が実際に1対1であるという事実も適切に表現します。
単数形が一般的に受け入れられているデータベーステーブル名の普及傾向に従ってみませんか?そこにいた、それをやった - 再利用しましょう。
APIコンシューマの観点からは、エンドポイントは予測可能であるべきです。
理想的には….
GET /resources
はリソースのリストを返します。GET /resource
は400レベルのステータスコードを返します。GET /resources/id/{resourceId}
は1つのリソースを持つコレクションを返すべきです。GET /resource/id/{resourceId}
はリソースオブジェクトを返すべきです。POST /resources
はリソースを一括作成します。POST /resource
はリソースを作成するはずです。PUT /resource
はリソースオブジェクトを更新する必要があります。PATCH /resource
は、変更された属性のみをポストすることによってリソースを更新します。PATCH /resources
は、変更された属性のみをポストしてリソースを一括更新します。DELETE /resources
はすべてのリソースを削除します。冗談:400ステータスコードDELETE /resource/id/{resourceId}
このアプローチは最も柔軟で機能が豊富ですが、開発には最も時間がかかります。したがって、急いでいる場合(これは常にソフトウェア開発の場合です)、エンドポイントにresource
、または複数形にresources
と名前を付けるだけです。すべての複数形が 's'で終わっているわけではないので、プログラム的にイントロスペクトし評価するオプションを与えるので、私は単数形を好む。
すべてのことを言って、開発者が最も一般的に使用された練習が選んだどんな理由のためにでも複数形を使うことです。これが最終的に私が選んだルートであり、あなたがgithub
やTwitter
のような人気のあるAPIを見れば、これが彼らがすることです。
決定基準は次のとおりです。
だからあなた次第です。あなたが何をしていようとも一貫しています。
非常に多くの人々が複数形名詞バンドワゴンに飛びつくだろうということに驚きました。単数形から複数形への変換を実装するとき、あなたは不規則な複数形の名詞を世話していますか?あなたは痛みを楽しんでいますか?
http://web2.uvcs.uvic.ca/elc/studyzone/330/grammar/irrplu.htm を参照してください。
不規則な複数形には多くの種類がありますが、これらが最も一般的です。
名詞型複数形を形成する例
Ends with -fe Change f to v then Add -s
knife knives
life lives
wife wives
Ends with -f Change f to v then Add -es
half halves
wolf wolves
loaf loaves
Ends with -o Add -es
potato potatoes
tomato tomatoes
volcano volcanoes
Ends with -us Change -us to -i
cactus cacti
nucleus nuclei
focus foci
Ends with -is Change -is to -es
analysis analyses
crisis crises
thesis theses
Ends with -on Change -on to -a
phenomenon phenomena
criterion criteria
ALL KINDS Change the vowel or Change the Word or Add a different ending
man men
foot feet
child children
person people
tooth teeth
mouse mice
Unchanging Singular and plural are the same
sheep deer fish (sometimes)
私は単純さと一貫性の両方のために単数形を使うことを好みます。
たとえば、次のURLを考えます。
/ customer/1
私は顧客を顧客コレクションとして扱いますが、簡単にするために、収集部分は削除されています。
もう一つの例:
/装備/ 1
この場合、機器は正しい複数形ではありません。そのため、機器コレクションとして扱い、簡単にするためにコレクションを削除することで、お客様のケースと一致させることができます。
私の2つのセント:時間を複数形から単数形、またはその逆に変更する方法は、CPUサイクルの無駄です。私は老人かもしれませんが、私の時間では物事は同じと呼ばれていました。人に関する方法を調べるにはどうすればよいですか。望ましくない副作用がない限り、通常の表現は人と人の両方をカバーしません。
英語の複数形は非常に恣意的である可能性があり、それらはコードを不必要に邪魔します。 1つの命名規則に従います。コンピュータ言語は、自然言語を模倣するのではなく、数学的な明快さについてのものであると考えられていました。
命名規則では、「ただ1つ選択してそれに固執する」と言うのが通常安全です。
ただし、RESTを多くの人に説明しなければならない場合は、ファイルシステム上の パスとしてエンドポイントを表す がそれを行う最も表現的な方法です。
ステートレス(ファイルが存在するか存在しないか)、階層的、単純、そしておなじみです - ローカルであろうとhttp経由であろうと、静的ファイルにアクセスする方法はすでに知っています。
そしてその文脈の中では、言語学のルールはあなたを次のようにすることしかできません:
ディレクトリには複数のファイルやサブディレクトリ、あるいはその両方を含めることができるため、その名前は複数形にする必要があります。
そして私はそれが好きです。
その一方で、それはあなたのディレクトリですが、それがあなたが望むものであれば "a-resource-or-multiple-resources"と名付けることができます。それは本当に重要なことではありません。
重要なことは、 "resourceS"という名前のディレクトリの下に "123"という名前のファイルを置くと(/resourceS/123
という結果になる)、/resource/123
経由でアクセスできるとは期待できないことです。
必要以上に賢くしようとしないでください - あなたが現在アクセスしているリソースの数に応じて複数から単一へと変更することは審美的にもあるかもしれませんが、それは効果的ではなく意味がありません。 階層構造 システム。
注:技術的には、 "シンボリックリンク"を作成することができます。そのため、/resources/123
には/resource/123
経由でもアクセスできますが、前者はまだ存在している必要があります。
ルートのIDはリストのインデックスと同じように表示される必要があり、それに応じてネーミングが続行されます。
numbers = [1, 2, 3]
numbers GET /numbers
numbers[1] GET /numbers/1
numbers.Push(4) POST /numbers
numbers[1] = 23 UPDATE /numbers/1
しかし、一部のリソースは、ルートが1つしかないため、またはユーザーが複数にアクセスできないため、ルートでIDを使用しません。したがって、これらはリストではありません。
GET /dashboard
DELETE /session
POST /login
GET /users/{:id}/profile
UPDATE /users/{:id}/profile
私はほとんどの人が単数形を使うか単数形を使うかを決めることの間にいることを知っています。ここで対処されていない問題は、クライアントがあなたがどれを使用しているかを知る必要があるということです、そして、彼らは常に間違いを犯しそうです。これが私の提案の由来です。
両方ともどうですか?そして、それは、あなたのAPI全体に単数形を使用し、それから複数形で行われたリクエストを単数形に転送するルートを作成することを意味します。例えば:
GET /resources = GET /resource
GET /resources/1 = GET /resource/1
POST /resources/1 = POST /resource/1
...
あなたは写真を撮ります。誰も間違っていない、最小限の努力、そしてクライアントはそれを常に正しくするでしょう。
すべてのメソッドに複数形を使用することは、少なくとも1つの側面でより実用的です。Postman(または同様のツール)を使用してリソースAPIを開発およびテストしている場合、GETからPUTにPOSTなど。
どちらの表現も便利です。便宜上単数形を使っていましたが、変曲は難しいかもしれません。厳密に単数形のREST APIの開発における私の経験では、エンドポイントを使用する開発者は、結果の形がどうなるかについて確信が持てません。私は今、反応の形を最もよく表す言葉を使うことを好む。
あなたのすべてのリソースがトップレベルであるなら、あなたは特異表現で逃げることができます。変曲を避けることは大きな勝利です。
リレーションに関するクエリを表すために何らかのディープリンクを作成している場合は、より厳密な規約を使用することで、開発者があなたのAPIに対して書くのを助けることができます。
私の慣例では、URIの各レベルの深さは親リソースとの対話を記述しており、完全なURIは暗黙のうちに取得されているものを記述するべきです。
次のようなモデルがあるとします。
interface User {
<string>id;
<Friend[]>friends;
<Manager>user;
}
interface Friend {
<string>id;
<User>user;
...<<friendship specific props>>
}
クライアントが特定のユーザーの特定の友人のマネージャを取得できるようにするためのリソースを提供する必要がある場合は、次のようになります。
GET /users/{id}/friends/{friendId}/manager
以下にいくつかの例を示します。
GET /users
- グローバルユーザーコレクション内のユーザーリソースを一覧表示するPOST /users
- グローバルユーザーコレクションに新しいユーザーを作成するGET /users/{id}
- グローバルユーザーコレクションから特定のユーザーを取得するGET /users/{id}/manager
- 特定のユーザーの管理者を取得するGET /users/{id}/friends
- ユーザーの友達の一覧を取得するGET /users/{id}/friends/{friendId}
- ユーザーの特定の友達を取得するLINK /users/{id}/friends
- このユーザーに友達の関連付けを追加するUNLINK /users/{id}/friends
- このユーザーから友達の関連付けを削除する各レベルがどのように行動できる親にマッピングされているかに注目してください。同じオブジェクトに対して異なる親を使用することは直感に反するものです。 GET /resource/123
でリソースを取得しても、新しいリソースを作成することがPOST /resources
で行われるべきであるという示唆は残りません
どうですか?
/resource/
(/resource
ではありません)
/resource/
は、フォルダに "リソース"という名前のものが含まれていることを意味し、それは "リソース"フォルダです。
また、データベーステーブルの命名規則も同じだと思います。たとえば、「user」というテーブルは「userテーブル」で、「user」という名前のものも含まれています。
チェックアウトGoogleの APIデザインガイド:リソース名 リソースの命名に関する別の見解。
要するに:
|--------------------------+---------------+-------------------+---------------+--------------|
| API Service Name | Collection ID | Resource ID | Collection ID | Resource ID |
|--------------------------+---------------+-------------------+---------------+--------------|
| //mail.googleapis.com | /users | /[email protected] | /settings | /customFrom |
| //storage.googleapis.com | /buckets | /bucket-id | /objects | /object-id |
|--------------------------+---------------+-------------------+---------------+--------------|