はじめに
エキサイト株式会社 21卒 バックエンドエンジニアの山縣です。 Spring Boot / Javaで既存システムのリビルドを進めてHTTPステータスコードの実装を調べている途中に、ふと他の言語の実装が気になり、普段趣味で使用しているPythonとGoのソースコードを見てみました。 本記事では、Java、Python、GoのHTTPステータスコードの実装について紹介します。
調査環境
今回調査した環境は以下のとおりです。
- Java(Spring Framework 5.3.7)
org/springframework/http/HttpStatus.java
- Python 3.9.7
http/__init__.py
- Go 1.17
src/net/http/status.go
Javaのステータスコード
Java(Spring Framework)のステータスコードはenumを使って実装されていました。
ステータスコードごとに要素が存在し、とてもわかりやすい実装になっています。
また、HttpStatusには2xx系のステータスコードかどうかを判定するis2xxSuccessful()
メソッドや、エラーかどうかの判定するisError()
メソッドが実装されています。ここに挙げたメソッド以外にもHTTPステータスコードに関係する便利なメソッドがいくつか実装されているので、必要に応じて活用していきたいです。
public enum HttpStatus { OK(200, Series.SUCCESSFUL, "OK"), CREATED(201, Series.SUCCESSFUL, "Created"), ACCEPTED(202, Series.SUCCESSFUL, "Accepted"), public boolean is2xxSuccessful() { return (series == Series.SUCCESSFUL); } public boolean isError() { return (is4xxClientError() || is5xxServerError()); } private final int value; private final Series series; private final String reasonPhrase; HttpStatus(int value, Series series, String reasonPhrase) { this.value = value; this.series = series; this.reasonPhrase = reasonPhrase; } public int value() { return this.value; } }
使い方
HttpStatusはvalue()
メソッドを呼び出すことでステータスコードを取得することでき、getReasonPhrase()
メソッドを呼び出すことでメッセージを取得することができます。
// 引数にHttpStatus.CREATEDを渡して実行 public void check(HttpStatus status) { System.out.println(status.value()); // → 201 System.out.println(status.getReasonPhrase()); // → Created }
Pythonのステータスコード
Pythonの標準ライブラリのステータスコードは、IntEnumを継承して実装されていました。 Javaのステータスコードの実装と比較的似ていますが、こちらはステータスコードのみ実装されており、ちょっとしたことで使える便利なメソッドの実装はありませんでした。
class HTTPStatus(IntEnum): OK = 200, 'OK', 'Request fulfilled, document follows' CREATED = 201, 'Created', 'Document created, URL follows' ACCEPTED = (202, 'Accepted', 'Request accepted, processing continues off-line')
使い方
HTTPStatusは、value
を呼び出すことでステータスコードを取得することができ、phrase
を呼び出すことでメッセージを取得することができます。
また、IntEnumを継承しているためint型と比較することができます。
# 引数にHTTPStatus.CREATEDを渡して実行 def check(status: http.HTTPStatus): print(status.value) # → 201 print(status.phrase) # → Created print(status == http.HTTPStatus.CREATED) # → True print(status == 201) # → True
Goのステータスコード
Goには上記に挙げたenumのような機能はありません。 Goでは、定数とmapを組み合わせてHTTPステータスコードを実装しています。 そのため、上記2つとは異なり、HttpStatus型のようなものはないため、ステータスコードはint型として扱わなければなりません。
package http const ( StatusOK = 200 // RFC 7231, 6.3.1 StatusCreated = 201 // RFC 7231, 6.3.2 StatusAccepted = 202 // RFC 7231, 6.3.3 ) var statusText = map[int]string{ StatusOK: "OK", StatusCreated: "Created", StatusAccepted: "Accepted", } func StatusText(code int) string { return statusText[code] }
使い方
とてもシンプルです!
// 引数にhttp.StatusCreatedを渡して実行 func check(code int) { fmt.Println(code) //→ 201 fmt.Println(http.StatusText(code)) // → Created }
おわりに
本記事ではJava、Python、GoのHTTPステータスコードの実装についてまとめました。 実際にソースコードを比較してみると、各言語の特色が出てきて面白かったです。 最後まで読んでいただき、ありがとうございました!