簡単なAPIを作ってみた
APIについて色々読んだりしてみたものの、設計ルールをがっつり盛り込んでAPIを設計するほどのアイデアが出てこなかったのでまずはAPIを作る事に慣れようの回とした。
今回はローカルホストだけどこんな感じに返ってくるAPIを作ってみた。
参考リンク
今回はこちらをメインに参考
Go公式で参考にしたページ
APIの設計ルール諸々紹介されている記事
準備
使用したのはGo言語。PythonのFlaskでも作れるらしい。
(上記に挙げていないけど)色々なAPIの作成に関する記事を見て、読みやすいなと思った事と、Go言語に触った事がないので触ってみたくてGoを使用した。
- 開発環境:VS Code
VS CodeでGoのフォルダとファイルを作成する。例えばこんな感じ。
この時点で適当にコード書いてデバッグするとgo.modファイルが見つからないよというエラーが発生する。(画像はgo.mod作成後。go.modがない場合にデバッグすると見つからないエラーが発生する。)
なのでVS Codeのターミナルでコマンド go mod init <好きなモジュール名(今回はapi)>
を実行してファイルを作成する。
作成されたファイルの中身はこちら(一応備忘録として)。
作成
作成したコードはこちら。
Goのコードが手探り状態だったので、全然もう少し上手く書き直せそうではある。
package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
)
type Holiday struct {
MonthMessage string
Date string
Holiday_Data string
}
func handleRequests() {
http.HandleFunc("/", homePage)
http.HandleFunc("/January", returnHolidayData_Jan)
// 省略しているのでコメントアウト http.HandleFunc("/February", returnHolidayData_Feb)
// 省略しているのでコメントアウト http.HandleFunc("/March", returnHolidayData_Mar)
// 省略しているのでコメントアウト http.HandleFunc("/April", returnHolidayData_Apr)
http.HandleFunc("/May", returnHolidayData_May)
log.Fatal(http.ListenAndServe(":8081", nil))
}
func homePage(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Welcome to the HomePage!")
fmt.Println("Endpoint Hit: homePage")
}
func returnHolidayData_Jan(w http.ResponseWriter, r *http.Request) {
holiday := []Holiday{}
arr_date := []string{"1/1", "1/8"}
arr_name := []string{"元日", "成人の日"}
for i := 0; i < 2; i++ {
Msg_txt := fmt.Sprintf(" 1月の%dつ目のお休み", i+1)
holiday = append(
holiday,
Holiday{MonthMessage: Msg_txt, Date: arr_date[i], Holiday_Data: arr_name[i]})
}
json.NewEncoder(w).Encode(holiday)
}
//2月~4月は省略
func returnHolidayData_May(w http.ResponseWriter, r *http.Request) {
holiday := []Holiday{}
arr_date := []string{"5/3", "5/4", "5/5"}
arr_name := []string{"憲法記念日", "みどりの日", "こどもの日"}
for i := 0; i < 3; i++ {
Msg_txt := fmt.Sprintf(" 5月の%dつ目のお休み", i+1)
holiday = append(
holiday,
Holiday{MonthMessage: Msg_txt, Date: arr_date[i], Holiday_Data: arr_name[i]})
}
json.NewEncoder(w).Encode(holiday)
}
func main() {
handleRequests()
}
コードの詳細
基本的にはメインに参考した記事を元に作成した。
自分の中でへぇ~となったところを以下でピックアップ。
import
import (
"encoding/json"
"fmt"
"log"
"net/http"
)
作るために上記4つのインポートが必要。
net/http
はAPIリクエスト、レスポンスを処理するために必要なHTTPサーバを実装するために必要なパッケージ。
encoding/json
はJSONデータを扱うために必要なパッケージ。
JSONの中身の型
type Holiday struct {
MonthMessage string
Date string
Holiday_Data string
}
それぞれの値は文字列型に設定。
実際に返す内容は以下のようになる。
func handleRequests()とhttp.HandleFunc
func handleRequests() {
http.HandleFunc("/", homePage)
http.HandleFunc("/January", returnHolidayData_Jan)
ここではリクエストのURI(/
や/January
)からどの関数を呼び出すかを決めている。リクエストが来た時にどのような内容を返すのかのハンドリングはここで設定できるのだなと。もっとこうびっくりするようなコードを書くのかと勝手に想像していました何故か。
ポートの指定
log.Fatal(http.ListenAndServe(":8081", nil))
リクエストを受け付けるポート番号はこちらで指定。他の通信と競合しないように気を付ける。
実際のリクエストも、リクエストを受け付けるポートを指定している事がわかる。
呼び出される関数の中身
func returnHolidayData_May(w http.ResponseWriter, r *http.Request) {
holiday := []Holiday{}
arr_date := []string{"5/3", "5/4", "5/5"}
arr_name := []string{"憲法記念日", "みどりの日", "こどもの日"}
for i := 0; i < 3; i++ {
Msg_txt := fmt.Sprintf(" 5月の%dつ目のお休み", i+1)
holiday = append(
holiday,
Holiday{MonthMessage: Msg_txt, Date: arr_date[i], Holiday_Data: arr_name[i]})
}
json.NewEncoder(w).Encode(holiday)
}
呼び出される関数returnHolidayData_May
と呼び出し元はこちら。
func handleRequests() {
//省略
http.HandleFunc("/May", returnHolidayData_May)
実際のJSONの中身は呼び出される関数returnHolidayData_May
にて作成。
上記で紹介したJSONの中身の型Holiday
のholiday
を宣言。ややこしい。
クラスとインスタンスに似てるなとふんわり感じた。
今回は1月~5月ごとにその月の休日をレスポンスとして返す設計とした。
そのため、returnHolidayData_May
では、5月の休日の日付、休日の名前を配列に格納。
holiday := []Holiday{}
arr_date := []string{"5/3", "5/4", "5/5"}
arr_name := []string{"憲法記念日", "みどりの日", "こどもの日"}
for文は休日の数だけ回す。
数字直入れではなくて配列の長さで回した方が良いね。
JSONの中身の型Holiday
のそれぞれの項目MonthMessage
、Date
、Holiday_Data
に値を入れつつ、holiday
に追加して返す。
for i := 0; i < 3; i++ {
Msg_txt := fmt.Sprintf(" 5月の%dつ目のお休み", i+1)
holiday = append(
holiday,
Holiday{MonthMessage: Msg_txt, Date: arr_date[i], Holiday_Data: arr_name[i]})
}
諸々値を入れたholiday
を最後にエンコード。
json.NewEncoder(w).Encode(holiday)
デバッグしてレスポンスを確認
ポップアップが表示されるので「許可」をクリック。
これでリクエスト、レスポンスを処理できる状態となる。
Postmanで/May
のリクエストを送信すると200 OK
と返ってきている事を確認できる。
holiday
の中身がレスポンスとして返ってきている事が分かる。
さいごに
Go言語の書き方に慣れてくればもう少しレスポンスの中身は綺麗に書けそうだと感じた。
それと次回はAPIの設計ルールを元に、DBの用意と、メソッド周り含めて作りたいAPIの構成を考えた上で、リベンジしたい。