REST APIのリソース設計(エンドポイント設計)を初心者向けにわかりやすく解説!
新人
「REST APIってよく聞きますけど、そもそも何なんですか?」
先輩
「REST APIは、Webアプリケーションでよく使われる仕組みで、HTTPを使ってデータのやりとりをするんだ。」
新人
「データのやりとりって、どういうふうにするんですか?」
先輩
「それを理解するには、リソースやエンドポイントの設計について知っておくと良いよ。順番に説明していこう。」
1. REST APIとは何か?
REST APIとは、「Representational State Transfer(表現状態の転送)」という設計スタイルに基づいたAPI(アプリケーションプログラミングインターフェース)のことです。Webシステムにおいて、クライアントとサーバーがHTTPを使ってデータをやり取りするためのルールや方法を定めています。
例えば、フロントエンドから「商品一覧を取得したい」というリクエストがあった場合、サーバーはそのリクエストに応じて商品データをJSON形式などで返します。これがREST APIの基本的な考え方です。
REST APIは「HTTPのGET、POST、PUT、DELETEといったメソッド」と「リソースを表すエンドポイントURL」を組み合わせて設計されます。これにより、シンプルでわかりやすく、拡張性の高いAPI設計が可能になります。
2. リソースとは何か?なぜリソース設計が重要なのか?
REST APIにおける「リソース」とは、対象となるデータそのものを意味します。例えば、「ユーザー情報」や「商品情報」、「注文履歴」などがリソースの一例です。
このリソースを正しく設計することで、API全体の使いやすさやメンテナンス性が大きく向上します。具体的には、リソースを「名詞」で表し、それに対応する操作をHTTPメソッドで表すようにします。
例えば、ユーザー一覧を取得したい場合は、以下のようなURL設計になります。
GET /users
「/users」がリソースで、「GET」が取得操作を意味しています。こうした設計により、誰が見ても直感的に意味が分かるAPIになります。
また、リソース設計は一貫性が大事です。例えば、「/getUser」「/fetchUserInfo」などバラバラな命名にすると、利用者が混乱します。リソース=名詞のルールを守り、統一されたエンドポイント設計を行いましょう。
3. エンドポイントの基本構造(URL設計の原則)
REST APIのエンドポイントは、リソースを表すURLのことです。基本的な構造は非常にシンプルで、「ドメイン名 + リソースパス」で構成されます。
例えば、商品情報を扱うAPIのエンドポイント設計は次のようになります。
GET /products // 商品一覧の取得
GET /products/1 // 商品IDが1の情報を取得
POST /products // 商品の新規登録
PUT /products/1 // 商品IDが1の情報を更新
DELETE /products/1 // 商品IDが1の情報を削除
このように、GET、POST、PUT、DELETEといったHTTPメソッドによって、それぞれの操作を表現します。URL自体は操作を含まず、常にリソース名(名詞)で表すことが重要です。
Springでこうしたエンドポイントを定義する場合は、以下のように@Controllerを使って実装します。
@Controller
@RequestMapping("/products")
public class ProductController {
@GetMapping
public String listProducts(Model model) {
// 商品一覧取得の処理
return "product/list";
}
@GetMapping("/{id}")
public String getProduct(@PathVariable Long id, Model model) {
// 商品詳細取得の処理
return "product/detail";
}
@PostMapping
public String createProduct(@ModelAttribute Product product) {
// 新規登録処理
return "redirect:/products";
}
@PostMapping("/{id}")
public String updateProduct(@PathVariable Long id, @ModelAttribute Product product) {
// 更新処理(本来はPUTが望ましいが、HTMLフォームの制限でPOST使用)
return "redirect:/products/" + id;
}
@PostMapping("/{id}/delete")
public String deleteProduct(@PathVariable Long id) {
// 削除処理(DELETEの代わりにPOST)
return "redirect:/products";
}
}
Spring MVCではHTMLフォームの制約によりPUTやDELETEが使えないため、POSTで代用するのが一般的です。
また、Pleiades環境では、Gradleでプロジェクトを作成し、依存関係もチェックボックスで追加できます。設定ファイルに直接触れずに環境構築できるため、初心者にも扱いやすいです。
このように、REST APIのリソース設計とエンドポイント設計は、直感的で一貫性のあるAPIを提供するために欠かせない要素です。次回はHTTPメソッドの使い分けや、パラメータ設計について詳しく見ていきましょう。
4. HTTPメソッド(GET、POST、PUT、DELETE)の使い分けと意味
REST APIでは、HTTPメソッドを使って、リソースに対する操作を表現します。ここでは、代表的なメソッドであるGET、POST、PUT、DELETEについて、それぞれの意味と使い分けを解説します。
GETは、データを「取得」するためのメソッドです。URLにパラメータを付けて、サーバーから情報を受け取るだけの安全な操作に使います。
POSTは、新しいデータを「作成」する際に使用します。フォームの送信や新規登録に使うことが多いです。
PUTは、既存のデータを「更新」するための操作です。対象のリソース全体を上書きする意味を持ちます。
DELETEは、指定されたリソースを「削除」するために使います。これらのメソッドは、それぞれに明確な役割があります。
Spring MVCで@Controllerを使って実装する場合、HTTPメソッドに応じたアノテーションを使います。以下はその基本的な書き方です。
@Controller
@RequestMapping("/users")
public class UserController {
@GetMapping
public String listUsers(Model model) {
return "user/list";
}
@PostMapping
public String createUser(@ModelAttribute User user) {
return "redirect:/users";
}
@PutMapping("/{id}")
public String updateUser(@PathVariable Long id, @ModelAttribute User user) {
return "redirect:/users/" + id;
}
@DeleteMapping("/{id}")
public String deleteUser(@PathVariable Long id) {
return "redirect:/users";
}
}
ただし、前回も述べた通り、HTMLフォームではPUTやDELETEが直接使えないため、POSTで代用するケースも多く見られます。
5. RESTらしいエンドポイント設計とは?
RESTful設計では、エンドポイントは操作を含めずに「リソース名(名詞)」だけで表すのが基本です。たとえば、「ユーザーの情報を取得する」という操作でも、エンドポイントは以下のように設計します。
GET /users // 全ユーザーを取得
GET /users/10 // IDが10のユーザーを取得
POST /users // 新しいユーザーを作成
PUT /users/10 // IDが10のユーザーを更新
DELETE /users/10 // IDが10のユーザーを削除
このように、エンドポイントの命名は「動詞を避け、名詞を使う」のが鉄則です。「/getUser」「/createUser」などのように動詞を含めてしまうと、RESTの原則から外れてしまいます。
また、エンドポイントの階層構造も重要です。例えば、ユーザーに紐づく注文情報を扱う場合、次のようなURL設計が適切です。
GET /users/10/orders // ユーザーIDが10の注文一覧を取得
GET /users/10/orders/5 // ユーザーIDが10の注文IDが5の詳細取得
このようにリソースの関係性をURLで表現することで、APIの構造がわかりやすくなり、メンテナンス性も高まります。
Springの@Controllerでこのような階層的エンドポイントを実装する場合、複数の@RequestMappingを組み合わせて使用します。
@Controller
@RequestMapping("/users/{userId}/orders")
public class OrderController {
@GetMapping
public String listOrders(@PathVariable Long userId, Model model) {
return "order/list";
}
@GetMapping("/{orderId}")
public String getOrder(@PathVariable Long userId, @PathVariable Long orderId, Model model) {
return "order/detail";
}
}
URLに階層構造を持たせることで、リソース同士の関連性が明確になり、APIの設計として非常に自然な形になります。
6. パスパラメータとクエリパラメータの違いと使い分け
REST APIでは、URLの中で値を渡す方法として、「パスパラメータ」と「クエリパラメータ」の2つがあります。それぞれの違いと使い分けを理解することが、パラメータ設計においてとても重要です。
パスパラメータは、URLの一部として指定する値で、特定のリソースを識別するために使われます。以下はその例です。
GET /products/5 // IDが5の商品を取得
この場合、「5」という値は商品IDであり、どの商品かを一意に示す役割を持ちます。
一方で、クエリパラメータは、URLの末尾に「?」を付けて追加する形式で、条件やオプションを指定するために使われます。以下はその例です。
GET /products?category=book&page=2
このように、クエリパラメータは「一覧のフィルタ」「ページ番号」「検索条件」などに使われるのが一般的です。
Springでの実装では、パスパラメータは@PathVariable、クエリパラメータは@RequestParamで受け取ります。具体的なコードは以下の通りです。
@Controller
@RequestMapping("/products")
public class ProductController {
@GetMapping("/{id}")
public String getProduct(@PathVariable Long id, Model model) {
return "product/detail";
}
@GetMapping
public String listProducts(@RequestParam(required = false) String category,
@RequestParam(defaultValue = "1") int page,
Model model) {
return "product/list";
}
}
このように、リソースの一意な識別にはパスパラメータを使い、条件指定やオプションにはクエリパラメータを使うのが、REST APIにおけるベストプラクティスです。
どちらを使うかで迷った場合は、「それがリソースの特定に不可欠かどうか」を基準に判断するとよいでしょう。
7. よくある設計ミスとその回避方法(動詞エンドポイント・複雑なURLなど)
初心者がREST APIのエンドポイント設計でよくやってしまうミスとして、動詞を使ってしまうケースがあります。例えば以下のようなエンドポイントはNGです。
GET /getUser
POST /createOrder
DELETE /deleteProduct
これらは一見わかりやすく見えますが、RESTの原則から外れた設計です。本来のREST APIでは、エンドポイントは「名詞」で表し、操作はHTTPメソッドで表現するのが基本です。
正しくは、以下のように設計します。
GET /users
POST /orders
DELETE /products/1
このようにすることで、誰が見ても直感的に理解できるREST APIになります。
また、複雑すぎるURL構造もよくある落とし穴です。例えば以下のようなURLは避けるべきです。
GET /userManagement/getUserDetailsById/10
これは、リソースと操作が混在しており、どこに何があるのか非常に分かりにくくなっています。こうした場合も、リソースを明確に表し、URLはシンプルかつ階層的に設計しましょう。
GET /users/10
エンドポイントが深すぎたり、意味のない英数字を含んだパスを設けると、利用者が混乱する原因になります。常に読みやすく・予測しやすいURL設計を心がけましょう。
8. リソース設計のベストプラクティス(シンプル・予測可能・一貫性)
REST APIを設計するうえで重要なのは、「予測可能で一貫性のあるリソース設計」を行うことです。以下のようなポイントを押さえると、保守性の高いAPIになります。
① シンプルで直感的な命名
エンドポイントは極力短く、かつ意味が明確なものにしましょう。例えば「/users」はユーザーを、「/orders」は注文情報を示します。省略語や略語を多用すると逆に分かりづらくなるため避けるべきです。
② 複数形を使う
リソースは基本的に「一覧」を扱う可能性があるため、複数形で表現するのが一般的です。たとえば「/user」ではなく「/users」とすることで、複数のデータを返すことが自然に伝わります。
③ 一貫性を守る
API全体で命名規則やパターンに統一性があると、利用者はストレスなく操作できます。たとえば、「/users」「/products」「/orders」といった形で名詞ベースの設計を貫くことが大切です。
④ ステータスコードを正しく使う
エンドポイント設計とは少し離れますが、返すレスポンスのステータスコードもREST APIでは非常に重要です。「200 OK」「201 Created」「404 Not Found」「400 Bad Request」などを適切に使い分けましょう。
このようにリソース設計におけるベストプラクティスを守ることで、他の開発者や利用者にとっても親切で理解しやすいREST APIとなります。
9. Springでリソースエンドポイントを設計するサンプルコード(@Controller使用)
ここでは、Spring MVCを使ってREST APIのエンドポイントをどのように実装するかを、実際のコード例で紹介します。あくまで@Controllerを使用し、@RestControllerは使用しません。
今回は「ユーザー情報」を扱うエンドポイントを例に、基本的なGET・POST・PUT・DELETEの動作を想定した設計です。開発環境はpleiadesで構築し、Gradleベースのプロジェクトを前提としています。
@Controller
@RequestMapping("/users")
public class UserController {
@GetMapping
public String listUsers(Model model) {
// ユーザー一覧の取得
return "user/list";
}
@GetMapping("/{id}")
public String getUser(@PathVariable Long id, Model model) {
// 特定ユーザーの詳細取得
return "user/detail";
}
@GetMapping("/new")
public String showCreateForm(Model model) {
// ユーザー作成フォーム表示
model.addAttribute("user", new User());
return "user/create";
}
@PostMapping
public String createUser(@ModelAttribute User user) {
// ユーザー新規登録処理
return "redirect:/users";
}
@GetMapping("/{id}/edit")
public String showEditForm(@PathVariable Long id, Model model) {
// 編集フォームの表示処理
return "user/edit";
}
@PostMapping("/{id}")
public String updateUser(@PathVariable Long id, @ModelAttribute User user) {
// 更新処理(実際はPUTが理想だがPOSTで対応)
return "redirect:/users/" + id;
}
@PostMapping("/{id}/delete")
public String deleteUser(@PathVariable Long id) {
// 削除処理(DELETEではなくPOSTで対応)
return "redirect:/users";
}
}
このようにSpringでは、各エンドポイントに対応するメソッドを@GetMappingや@PostMappingで紐づけて実装します。
注意点:
- PUTやDELETEはHTMLフォームから直接呼び出せないため、
POSTで代用するのが一般的です。 - リソース設計を意識し、
/createUserや/deleteUserといった動詞を含むパスは避けています。 - ファイル名の構成(例:user/detail.htmlなど)も、リソース名に揃えることで整合性が取れます。
この設計方針に従えば、REST APIの原則に沿った予測可能な設計が実現できます。Springとpleiadesを使えば、直感的にコントローラやルーティングの構築が可能となり、初心者でも扱いやすい構成になります。