VS Codeに「REST Client」という拡張機能があるのはご存知でしょうか?
Rest Clientを使うことで簡単にHTTPリクエストを投げられます。今回はGET、POST、POSTでCSVをアップロードするリクエストを作って試しています。
概要
REST ClientはVS Codeの拡張機能で、上記のアイコンをインストールすれば使用できます。「~.http」のファイルを作成して、HTTPリクエストを投げられます。
PostManで十分ですが、例えばdocker上でしかAPIの通信ができない場合、docker上にPostManを動かすのは難しいと思います。REST Clientだと、VS CodeでDockerにSSHして、そこでRest Clientを実行できるので便利です。
実例
REST Clientを試せるリポジトリを作りましたので、こちらを元に説明をしていきます。HTTPサーバーはGoで動くようになっています。
REST Clientを実行するファイル
REST Clientは拡張子が「.http」か「.rest」のファイルで実行できます。
リクエストを区切る時は「###」を使用して、隣にどのようなリクエストかをコメントしてます。
リクエスト共有で同じ値を使用できるように変数を定義できます。@auth = ok_token
でauthという変数を定義していて、変数を使用する時は「{{ 変数 }}」と定義する。authの使い道は後述で説明するHTTPサーバーの認証で使用されます。
注意として、CSVをアップロードする処理はUTF-8で出力しているので、UTF-8で出力すると文字化けが起きる環境だとCSVアップロードの処理は失敗する。MacでShift-JISのCSVファイルを使おうとすると失敗します。
@auth = ok_token
### get
GET http://localhost:8080/test?id=3
### post
Post http://localhost:8080/test
Authorization: {{auth}}
{
"id": 3,
"name": "test"
}
### csv
Post http://localhost:8080/csv
Authorization: {{auth}}
Content-Type: multipart/form-data; boundary=boundary
--boundary
Content-Disposition: form-data; name="file"; filename="test.csv"
Content-Type: text/csv
< ./test.csv
--boundary
Content-Disposition: form-data; name="mode"
diff
--boundary--
HTTPサーバー
REST Clientを試すためのHTTPサーバーをGoで書いたもの。
「go run main.go」で実行ができる。
POSTとCSVのアップロード処理については、リクエストヘッダーのAuthorizationに「ok_token」が入っているかをチェックするミドルウェアを設定している。
package main
import (
"encoding/csv"
"encoding/json"
"io"
"log"
"net/http"
"github.com/go-chi/chi"
)
func main() {
r := getRouter()
err := http.ListenAndServe(":8080", r)
if err != nil {
log.Fatal(err)
}
}
func getRouter() chi.Router {
r := chi.NewRouter()
r.Get("/test", get)
// With(auth)で認証ミドルウェアを実行している
r.With(auth).Post("/test", post)
r.With(auth).Post("/csv", uploadCSV)
return r
}
// 認証のミドルウェア
// ヘッダーのAuthorizationに「ok_token」が入ってない場合は401エラーで返す
func auth(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
auth := r.Header.Get("Authorization")
if auth != "ok_token" {
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return
}
next.ServeHTTP(w, r)
})
}
// GETメソッド処理
// 受け取ったIDを返すだけ
func get(w http.ResponseWriter, r *http.Request) {
log.Println("Get!!")
id := r.FormValue("id")
type response struct {
ID string `json:"id"`
}
res := response{ID: id}
http.Header.Add(w.Header(), "content-type", "application/json")
http.Header.Add(w.Header(), "Access-Control-Allow-Origin", "*")
v, err := json.Marshal(res)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.Write(v)
}
// POSTメソッド処理
// 受け取ったID、名前を返すだけ
func post(w http.ResponseWriter, r *http.Request) {
log.Println("Post!!")
type response struct {
ID int `json:"id"`
Name string `json:"name"`
}
var res response
err := json.NewDecoder(r.Body).Decode(&res)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
log.Println(res)
http.Header.Add(w.Header(), "content-type", "application/json")
http.Header.Add(w.Header(), "Access-Control-Allow-Origin", "*")
v, err := json.Marshal(res)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.Write(v)
}
// CSVのアップロード
// CSVの中身を出力している
func uploadCSV(w http.ResponseWriter, r *http.Request) {
log.Println("CSV!!")
file, _, err := r.FormFile("file")
if err != nil {
log.Println(err)
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
defer file.Close()
csvReader := csv.NewReader(file)
for i := 0; ; i++ {
record, err := csvReader.Read()
// 最後の行なので終了
if err == io.EOF {
log.Println("EOF")
break
}
if err != nil {
log.Println("error", err)
break
}
log.Println(record)
}
}
実行結果
GET
Goの出力
2024/06/15 15:18:08 Get!!
RestClientの出力
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Content-Type: application/json
Date: Sat, 15 Jun 2024 06:18:08 GMT
Content-Length: 10
Connection: close
{
"id": "3"
}
POST
Goの出力
2024/06/15 15:27:11 Post!!
RestClientの出力
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Content-Type: application/json
Date: Sat, 15 Jun 2024 06:27:11 GMT
Content-Length: 22
Connection: close
{
"id": 3,
"name": "test"
}
CSV
Goの出力
2024/06/15 15:28:18 CSV!!
2024/06/15 15:28:18 [ID 名前]
2024/06/15 15:28:18 [1 Taro]
2024/06/15 15:28:18 [2 Jiro]
2024/06/15 15:28:18 EOF
RestClientの出力
HTTP/1.1 200 OK
Date: Sat, 15 Jun 2024 06:28:18 GMT
Content-Length: 0
Connection: close
まとめ
今回はREST Clientについて解説をしてきました。
解説していきた内容を使えば、大体のAPIに対して対応ができるようになります。DELETEやPATCHなどは紹介しませんでしたが、POSTと同じように使えます。
他にもGoについて解説をした記事がありますので、興味がありましたら、そちらも見てもらえたらと思います。
【おすすめ記事のリンク】
コメント