📘
Go言語 csv,json,バイナリファイルの受け取り方
はじめに
このページではGo言語でCSVやJSONのファイルをHTTPリクエストで受け取り、構造体にマッピングする実装例と、バイナリファイルを受け取って保存するパターンについて記述します。
1. JSONファイルの受け取りと構造体へのマッピング
まず、HTTPリクエストで送信されたJSONファイルを受け取り、それをGoの構造体にデコードする方法を説明します。
構造体の定義
受け取るJSONデータをマッピングするために、対応するGoの構造体を定義します。以下は、ユーザー情報を表す例です。
type User struct {
ID int `json:"id"`
Name string `json:"name"`
Email string `json:"email"`
}
実装例
次に、net/http
パッケージを使用して、JSONファイルを受け取るHTTPハンドラーを実装します。
package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
)
// User構造体を定義
type User struct {
ID int `json:"id"`
Name string `json:"name"`
Email string `json:"email"`
}
// JSONファイルを受け取るハンドラー関数
func uploadJSONHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
http.Error(w, "Invalid request method", http.StatusMethodNotAllowed)
return
}
var user User
// リクエストボディからJSONをデコード
err := json.NewDecoder(r.Body).Decode(&user)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
fmt.Fprintf(w, "Received User: %+v\n", user)
}
func main() {
http.HandleFunc("/upload-json", uploadJSONHandler)
log.Println("Server started at :8080")
log.Fatal(http.ListenAndServe(":8080", nil))
}
動作説明
- クライアントはHTTP POSTリクエストでJSONデータをサーバーに送信します。
- サーバーはリクエストを受け取り、
json.NewDecoder
を使ってJSONデータをUser
構造体にデコードします。 - デコードに成功すると、構造体にマッピングされたデータを出力します。
2. CSVファイルの受け取りと構造体へのマッピング
次に、HTTPリクエストで送信されたCSVファイルを受け取り、その内容をGoの構造体にマッピングする方法を説明します。
構造体の定義
CSVデータをマッピングするために、対応するGoの構造体を定義します。JSONと同様にユーザー情報を例とします。
type User struct {
ID int
Name string
Email string
}
実装例
encoding/csv
パッケージを使用して、CSVファイルを受け取るHTTPハンドラーを実装します。
package main
import (
"encoding/csv"
"fmt"
"io"
"log"
"net/http"
"strconv"
)
// User構造体を定義
type User struct {
ID int
Name string
Email string
}
// CSVファイルを受け取るハンドラー関数
func uploadCSVHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
http.Error(w, "Invalid request method", http.StatusMethodNotAllowed)
return
}
file, _, err := r.FormFile("file")
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
defer file.Close()
reader := csv.NewReader(file)
var users []User
// ヘッダーを読み飛ばす
if _, err := reader.Read(); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
// CSVを読み込んで構造体にマッピング
for {
record, err := reader.Read()
if err == io.EOF {
break
}
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
id, err := strconv.Atoi(record[0])
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
user := User{
ID: id,
Name: record[1],
Email: record[2],
}
users = append(users, user)
}
fmt.Fprintf(w, "Received Users: %+v\n", users)
}
func main() {
http.HandleFunc("/upload-csv", uploadCSVHandler)
log.Println("Server started at :8080")
log.Fatal(http.ListenAndServe(":8080", nil))
}
動作説明
- クライアントはHTTP POSTリクエストでCSVファイルをサーバーに送信します。
- サーバーはリクエストを受け取り、
encoding/csv
パッケージを使用してCSVデータを読み込みます。 - 読み込んだデータを
User
構造体に変換し、出力します。
3. バイナリファイルの受け取りと保存
バイナリファイル(例えば画像、動画、PDFなどの任意の形式のファイル)をHTTPリクエストで受け取り、サーバー上に保存する方法について説明します。
実装例
バイナリファイルを受け取るには、http.Request
のFormFile
メソッドを使用してファイルを取得し、ローカルディスクに保存します。
package main
import (
"fmt"
"io"
"log"
"net/http"
"os"
)
// バイナリファイルを受け取るハンドラー関数
func uploadFileHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
http.Error(w, "Invalid request method", http.StatusMethodNotAllowed)
return
}
file, header, err := r.FormFile("file")
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
defer file.Close()
// 保存先のパスを設定
dst, err := os.Create(fmt.Sprintf("./uploads/%s", header.Filename))
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
defer dst.Close()
// ファイルを保存
if _, err := io.Copy(dst, file); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
fmt.Fprintf(w, "File uploaded successfully: %s\n", header.Filename)
}
func main() {
// アップロードされたファイルを保存するディレクトリを作成
os.MkdirAll("./uploads", os.ModePerm)
http.HandleFunc("/upload-file", uploadFileHandler)
log.Println("Server started at :8080")
log.Fatal(http.ListenAndServe(":8080", nil))
}
動作説明
- クライアントはHTTP POSTリクエストでバイナリファイルをサーバーに送信します。
- サーバーはリクエストを受け取り、
r.FormFile("file")
を使ってアップロードされたファイルを取得します。 - ファイルを指定したディレクトリに保存し、アップロード完了メッセージを表示します。
まとめ
Go言語でJSONやCSVファイルをHTTPリクエストで受け取り、構造体にマッピングする方法と、バイナリファイルを受け取って保存する方法を説明しました。これらの手法を組み合わせることで、さまざまなタイプのデータを効率的に処理するAPIを構築できます。
Discussion