API開発で必須!HTTPステータスコードの基礎を初心者向けにやさしく解説
新人
「SpringでREST APIを作っているときに、HTTPステータスコードってよく見るんですが、あれって何なんですか?」
先輩
「あれは、サーバーがクライアントに返す応答の“状態”を表すコードなんだ。APIのエラーハンドリングやレスポンス設計にとても大切なんだよ。」
新人
「なるほど、でも具体的にどんなコードがあるんですか?数字だけで意味がわかりづらくて……」
先輩
「それじゃあ、API開発でよく使うHTTPステータスコードを順番に見ていこうか。まずは仕組みから説明するよ。」
1. HTTPステータスコードとは何か?
HTTPステータスコードとは、Webサーバーがクライアント(ブラウザやアプリなど)に対して、リクエストの結果を数字で伝えるための仕組みです。例えば、Springで作成したREST APIにアクセスしたとき、「成功した」「間違ったリクエストだった」「サーバー側で問題が発生した」などをステータスコードで伝えます。
ステータスコードは、3桁の数字で構成され、以下のような分類があります。
- 1xx:情報(ほとんど使用されません)
- 2xx:成功(例:200 OK)
- 3xx:リダイレクト
- 4xx:クライアントエラー(例:400 Bad Request)
- 5xx:サーバーエラー(例:500 Internal Server Error)
SpringのコントローラでHTTPステータスコードを制御することで、REST APIの設計がより明確になります。
2. なぜAPI開発でステータスコードが重要なのか
API開発では、HTTPステータスコードを正しく使うことで、クライアント側で適切なエラーハンドリングが可能になります。たとえば、200なら成功なので画面にデータを表示し、400ならユーザーの入力ミスとしてエラーメッセージを表示し、500ならサーバー側の不具合としてログに記録するなどの処理ができます。
たとえば、Springの@Controllerで作ったREST APIでは、以下のようにステータスコードを返すことができます。
@Controller
public class SampleApiController {
@GetMapping("/api/hello")
@ResponseBody
public ResponseEntity<String> hello() {
return new ResponseEntity<>("こんにちは、世界!", HttpStatus.OK); // 200
}
@PostMapping("/api/data")
@ResponseBody
public ResponseEntity<String> postData(@RequestBody String data) {
if (data == null || data.isEmpty()) {
return new ResponseEntity<>("リクエストが不正です", HttpStatus.BAD_REQUEST); // 400
}
return new ResponseEntity<>("受け取りました", HttpStatus.CREATED); // 201
}
@GetMapping("/api/error")
@ResponseBody
public ResponseEntity<String> serverError() {
return new ResponseEntity<>("サーバーエラーが発生しました", HttpStatus.INTERNAL_SERVER_ERROR); // 500
}
}
このように、SpringのResponseEntityとHttpStatusを組み合わせることで、REST APIで明確なレスポンスを返すことができるのです。
例えば、入力チェックで不正なデータが送られてきた場合は400 Bad Requestを返すようにすれば、クライアント側でも「ユーザーの入力に問題がある」とすぐに分かります。
3. よく使うHTTPステータスコード一覧
REST APIの開発において、頻繁に使用されるHTTPレスポンスコードは限られています。ここでは、Springを使ったWebアプリケーションで特によく使うステータスコードを一覧で紹介します。
- 200 OK:リクエストが正常に成功した場合に使用
- 201 Created:リソースの新規作成が成功した場合
- 204 No Content:処理は成功したが返す内容がない場合
- 400 Bad Request:不正なリクエスト(入力ミスなど)
- 401 Unauthorized:認証が必要なリソースに未認証でアクセスした場合
- 403 Forbidden:認可されていない操作(アクセス権限がない)
- 404 Not Found:リクエストされたリソースが存在しない
- 500 Internal Server Error:サーバー側でエラーが発生した場合
これらのコードを適切に使い分けることで、APIの設計が明確になり、フロントエンド側のエラーハンドリングも行いやすくなります。
4. 各ステータスコードの具体的な意味と使用例
ここからは、よく使われる各HTTPレスポンスコードについて、具体的な意味とSpringでの実装例を紹介していきます。
200 OK
HTTPステータスコード「200 OK」は、リクエストが正常に処理されたことを示します。一般的なGETリクエストなどで使われる基本のコードです。
@Controller
public class StatusController {
@GetMapping("/api/status/ok")
@ResponseBody
public ResponseEntity<String> getOk() {
return new ResponseEntity<>("リクエスト成功", HttpStatus.OK);
}
}
201 Created
「201 Created」は、新しいリソースが正常に作成された場合に使用します。POSTリクエストでの新規作成処理で使われます。
@Controller
public class StatusController {
@PostMapping("/api/status/create")
@ResponseBody
public ResponseEntity<String> createData(@RequestBody String body) {
return new ResponseEntity<>("リソースを作成しました", HttpStatus.CREATED);
}
}
204 No Content
「204 No Content」は、処理が成功したが返すデータが存在しない場合に使われます。DELETE処理や設定の更新時に便利です。
@Controller
public class StatusController {
@DeleteMapping("/api/status/delete")
@ResponseBody
public ResponseEntity<Void> deleteData() {
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
}
400 Bad Request
「400 Bad Request」は、リクエストが正しくない場合に使います。バリデーションエラーや入力ミス時によく使われるHTTPレスポンスコードです。
@Controller
public class StatusController {
@PostMapping("/api/status/bad")
@ResponseBody
public ResponseEntity<String> badRequest(@RequestBody String input) {
if (input == null || input.isEmpty()) {
return new ResponseEntity<>("入力エラー", HttpStatus.BAD_REQUEST);
}
return new ResponseEntity<>("受け付けました", HttpStatus.OK);
}
}
401 Unauthorized
「401 Unauthorized」は、認証が必要なリソースに対して未認証でアクセスされた場合に使います。トークン認証などで重要なHTTPレスポンスコードです。
@Controller
public class StatusController {
@GetMapping("/api/status/auth")
@ResponseBody
public ResponseEntity<String> unauthorized(@RequestHeader(value = "Authorization", required = false) String token) {
if (token == null) {
return new ResponseEntity<>("認証トークンがありません", HttpStatus.UNAUTHORIZED);
}
return new ResponseEntity<>("アクセス成功", HttpStatus.OK);
}
}
403 Forbidden
「403 Forbidden」は、認証はされているが、アクセス権限がない場合に使用します。ユーザーが管理者権限を持っていないときなどに返されます。
@Controller
public class StatusController {
@GetMapping("/api/status/forbidden")
@ResponseBody
public ResponseEntity<String> forbidden(@RequestParam String role) {
if (!"admin".equals(role)) {
return new ResponseEntity<>("アクセス権限がありません", HttpStatus.FORBIDDEN);
}
return new ResponseEntity<>("管理者ページへようこそ", HttpStatus.OK);
}
}
404 Not Found
「404 Not Found」は、指定されたリソースが存在しない場合に使用します。URLが間違っているときや、データが削除された場合などに使います。
@Controller
public class StatusController {
@GetMapping("/api/status/notfound")
@ResponseBody
public ResponseEntity<String> notFound(@RequestParam(required = false) String id) {
if (id == null) {
return new ResponseEntity<>("リソースが見つかりません", HttpStatus.NOT_FOUND);
}
return new ResponseEntity<>("リソースID:" + id, HttpStatus.OK);
}
}
500 Internal Server Error
「500 Internal Server Error」は、サーバー側で予期しないエラーが発生した場合に使用します。Springでは例外処理と連携してこのステータスを返すことが一般的です。
@Controller
public class StatusController {
@GetMapping("/api/status/error")
@ResponseBody
public ResponseEntity<String> internalError() {
try {
int result = 10 / 0; // 強制的な例外
return new ResponseEntity<>("成功", HttpStatus.OK);
} catch (Exception e) {
return new ResponseEntity<>("サーバー内部エラー", HttpStatus.INTERNAL_SERVER_ERROR);
}
}
}
5. 実際のAPI開発でよくあるステータスコードの使い方の注意点
API開発では、HTTPステータスコードを適切に使うことが非常に重要です。しかし、実際の開発現場では、以下のような注意点を意識しないと、思わぬ不具合を引き起こす可能性があります。
- 成功していないのに
200 OKを返してしまう - クライアントの入力ミスなのに
500 Internal Server Errorを返してしまう - リソースが見つからないのに
200 OKを返してしまう
たとえば、以下のようなコードは一見正しく見えますが、実際には適切なステータスコードを返していない可能性があります。
@Controller
public class BadApiController {
@GetMapping("/api/user")
@ResponseBody
public String getUser(@RequestParam String id) {
// リソースが見つからない場合でも200を返してしまっている
return "ユーザーが存在しません";
}
}
このような場合は、明示的に404 Not Foundを返すようにすべきです。クライアントにとっても、レスポンスの意味が明確になります。
6. よくある間違いとその防ぎ方
初心者が陥りやすい代表的な間違いとして、「エラーが起きているのに200を返してしまう」パターンがあります。たとえば、バリデーションエラーや未入力でも、処理が続いてしまい、200 OKを返すと、クライアント側では問題に気づけません。
@Controller
public class MistakeController {
@PostMapping("/api/submit")
@ResponseBody
public String submit(@RequestBody String name) {
if (name == null || name.isEmpty()) {
// 本来は400を返すべきだが、200のまま
return "名前が未入力です";
}
return "受け付けました";
}
}
このようなケースでは、以下のようにResponseEntityを使い、適切なHTTPステータスコードを返すことで、クライアントの誤解を防げます。
@Controller
public class FixedController {
@PostMapping("/api/submit")
@ResponseBody
public ResponseEntity<String> submit(@RequestBody String name) {
if (name == null || name.isEmpty()) {
return new ResponseEntity<>("名前が未入力です", HttpStatus.BAD_REQUEST);
}
return new ResponseEntity<>("受け付けました", HttpStatus.OK);
}
}
このように、処理結果に応じて正確なHTTPステータスコードを選ぶことが、APIエラー対応の第一歩です。
7. Springで独自エラーハンドリングを設定する方法(@ExceptionHandlerの基本)
APIの処理中に予期しないエラーが発生することもあります。そのような場合、Springでは@ExceptionHandlerを使って独自のエラーハンドリングを実装できます。
たとえば、指定したIDのリソースが見つからなかった場合にNotFoundExceptionを投げ、404 Not Foundを返すような構成にできます。
public class NotFoundException extends RuntimeException {
public NotFoundException(String message) {
super(message);
}
}
@Controller
public class ExceptionExampleController {
@GetMapping("/api/item")
@ResponseBody
public ResponseEntity<String> getItem(@RequestParam String id) {
if (!"123".equals(id)) {
throw new NotFoundException("アイテムが見つかりません");
}
return new ResponseEntity<>("アイテム情報", HttpStatus.OK);
}
@ExceptionHandler(NotFoundException.class)
@ResponseBody
public ResponseEntity<String> handleNotFound(NotFoundException ex) {
return new ResponseEntity<>(ex.getMessage(), HttpStatus.NOT_FOUND);
}
}
このようにすることで、例外が発生しても統一された形式でエラーを返すことができ、APIの利用者にもわかりやすくなります。
@ExceptionHandlerは、API全体で共通のエラーハンドリング処理を行う際にも非常に便利です。大規模なAPIになるほど、こうした例外処理の設計は重要になります。