Go言語 CSVやJSONファイルをレスポンスするAPIの実装例
はじめに
このページではGo言語でCSVやJSONファイルをレスポンスするAPIの実装例について記述します。
Go言語でのAPI実装概要
Go言語(Golang)はシンプルでパフォーマンスの高い言語であり、Web APIの実装においても非常に有用です。特に、JSONやCSV形式のデータをレスポンスとして返すAPIを作成するのは一般的なユースケースです。本記事では、net/http
パッケージを用いて、JSONおよびCSVファイルをレスポンスするAPIを実装する方法を紹介します。また、io.Copy
を使用して、効率的にファイルをストリーミングレスポンスする方法も解説します。
1. JSONファイルをレスポンスするAPIの実装
JSON形式はWeb APIでデータをやり取りする際の標準的な形式です。Go言語では、encoding/json
パッケージを使用してJSONデータをシリアライズ(エンコード)およびデシリアライズ(デコード)できます。
以下のコードは、JSON形式のデータを返す簡単なAPIを実装した例です。
package main
import (
"encoding/json"
"net/http"
)
type User struct {
ID int `json:"id"`
Name string `json:"name"`
Age int `json:"age"`
}
func main() {
http.HandleFunc("/json", func(w http.ResponseWriter, r *http.Request) {
// レスポンスヘッダーにContent-Typeを設定
w.Header().Set("Content-Type", "application/json")
// サンプルデータの作成
users := []User{
{ID: 1, Name: "Alice", Age: 30},
{ID: 2, Name: "Bob", Age: 25},
}
// JSONエンコードしてレスポンスとして送信
json.NewEncoder(w).Encode(users)
})
http.ListenAndServe(":8080", nil)
}
解説
-
http.HandleFunc("/json", func(w http.ResponseWriter, r *http.Request) {...})
でエンドポイント/json
を定義し、リクエストをハンドルします。 -
w.Header().Set("Content-Type", "application/json")
でレスポンスのContent-Type
をapplication/json
に設定します。 -
json.NewEncoder(w).Encode(users)
でusers
のデータをJSON形式にエンコードしてレスポンスとして返します。
2. CSVファイルをレスポンスするAPIの実装
CSV形式のデータを返すAPIの実装もGo言語で簡単に行えます。encoding/csv
パッケージを使用して、CSVデータを生成しレスポンスとして返します。
以下はCSV形式のデータを返すAPIの実装例です。
package main
import (
"encoding/csv"
"net/http"
)
func main() {
http.HandleFunc("/csv", func(w http.ResponseWriter, r *http.Request) {
// レスポンスヘッダーにContent-Typeを設定
w.Header().Set("Content-Type", "text/csv")
w.Header().Set("Content-Disposition", "attachment;filename=users.csv")
// CSVライターの作成
writer := csv.NewWriter(w)
defer writer.Flush()
// ヘッダーの書き込み
writer.Write([]string{"ID", "Name", "Age"})
// サンプルデータの書き込み
users := [][]string{
{"1", "Alice", "30"},
{"2", "Bob", "25"},
}
for _, user := range users {
writer.Write(user)
}
})
http.ListenAndServe(":8080", nil)
}
解説
-
http.HandleFunc("/csv", func(w http.ResponseWriter, r *http.Request) {...})
でエンドポイント/csv
を定義します。 -
w.Header().Set("Content-Type", "text/csv")
でレスポンスのContent-Type
をtext/csv
に設定し、Content-Disposition
ヘッダーを設定して、ファイルとしてダウンロードできるようにします。 -
csv.NewWriter(w)
でCSVライターを作成し、writer.Write
でCSV形式のデータを書き込みます。
3. io.Copyを使用したファイルストリーミングレスポンス
Go言語では、io
パッケージのio.Copy
関数を使用して、任意のファイルやデータのストリームを効率的にレスポンスとして返すことができます。これは、特に大きなファイルをストリーミングでクライアントに送信する際に便利です。Content-Type
ヘッダーをapplication/octet-stream
に設定することで、バイナリデータを扱う汎用的なレスポンスとして利用できます。
以下の例では、サーバーからローカルのファイルをダウンロード可能な形でストリーミングレスポンスするAPIを実装しています。
package main
import (
"io"
"net/http"
"os"
)
func main() {
http.HandleFunc("/file", func(w http.ResponseWriter, r *http.Request) {
// ファイルを開く
file, err := os.Open("example.txt")
if err != nil {
http.Error(w, "File not found.", http.StatusNotFound)
return
}
defer file.Close()
// レスポンスヘッダーにContent-Typeを設定
w.Header().Set("Content-Disposition", "attachment; filename=example.txt")
w.Header().Set("Content-Type", "application/octet-stream")
// ファイルの内容をレスポンスとしてコピー(ストリーミング)
if _, err := io.Copy(w, file); err != nil {
http.Error(w, "Failed to send file.", http.StatusInternalServerError)
}
})
http.ListenAndServe(":8080", nil)
}
解説
-
os.Open("example.txt")
でローカルのexample.txt
ファイルを開きます。 - エラーハンドリングとして、ファイルが見つからない場合には
http.Error
でエラーメッセージを返します。 -
w.Header().Set("Content-Disposition", "attachment; filename=example.txt")
で、クライアントにダウンロードさせるための設定を行います。 -
w.Header().Set("Content-Type", "application/octet-stream")
で、バイナリストリームとして送信するための汎用的なコンテンツタイプを設定します。 -
io.Copy(w, file)
で、ファイルの内容をレスポンスライターw
にストリーミングとしてコピーし、クライアントに送信します。
application/octet-stream
の利点
-
application/octet-stream
は、バイナリデータの送信において標準的なMIMEタイプであり、クライアント側で自動的にファイルをダウンロードする動作を促します。 - データ形式に関わらずファイルを安全に転送でき、特定のMIMEタイプに依存しないため汎用的に利用できます。
まとめ
Go言語を使ったAPIの実装はシンプルであり、特にJSONやCSV形式でデータを返すAPIの実装は、net/http
パッケージを利用することで簡単に行えます。io.Copy
を使用して、application/octet-stream
でファイルやストリームの内容を効率的にストリーミングレスポンスとして返すことも可能です。これらを活用することで、より柔軟で高効率なAPIの構築が可能になります。
Discussion