Last active
January 9, 2023 03:51
-
-
Save tomsato/64c22ebf60927fb17a5ec2bb5e595c13 to your computer and use it in GitHub Desktop.
Golangのnet/httpを利用したサンプルAPI
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"database/sql" | |
"encoding/json" | |
"fmt" | |
"io/ioutil" | |
"net/http" | |
"os" | |
_ "github.com/go-sql-driver/mysql" | |
) | |
// 環境変数の定義 | |
type appEnvironment struct { | |
username string | |
password string | |
} | |
// レスポンスJsonの定義 | |
type apiRequestResponse struct { | |
Code int `json:"code"` | |
Message string `json:"message"` | |
} | |
// DBのフィールド | |
type person struct { | |
id int | |
name string | |
} | |
func main() { | |
http.HandleFunc("/request", makeHandler(requestHandler)) | |
http.HandleFunc("/person", makeHandler(personHandler)) | |
http.ListenAndServe(":8080", nil) | |
} | |
// handlerに共通の変数を渡すため、3つの引数をもつfunctionを引数にとり、func(ResponseWriter, *Request)を返す | |
func makeHandler(fn func(http.ResponseWriter, *http.Request, appEnvironment)) http.HandlerFunc { | |
return func(w http.ResponseWriter, r *http.Request) { | |
fn(w, r, getAppEnvironment()) | |
} | |
} | |
// APIを叩いてレスポンスを返す | |
func requestHandler(w http.ResponseWriter, r *http.Request, env appEnvironment) { | |
// headerセット | |
w.Header().Set("Content-Type", "application/json; charset=utf-8") | |
// methodバリデーション | |
if r.Method != http.MethodGet { | |
w.WriteHeader(http.StatusMethodNotAllowed) | |
w.Write(createResponsJson(&apiRequestResponse{Code: 2001, Message: "Method not allowed."})) | |
return | |
} | |
// クエリパラメータ取得&バリデーションチェック | |
paramKey := r.URL.Query().Get("key") | |
if len(paramKey) == 0 { | |
w.WriteHeader(http.StatusBadRequest) | |
w.Write(createResponsJson(&apiRequestResponse{Code: 2002, Message: "key paramater not found."})) | |
return | |
} | |
// HTTPリクエストを行い結果をログに出力 | |
resp, _ := http.Get("http://httpbin.org/get?key=" + paramKey) | |
if resp == nil { | |
w.WriteHeader(http.StatusInternalServerError) | |
w.Write(createResponsJson(&apiRequestResponse{Code: 2003, Message: "HTTP Request failed."})) | |
return | |
} | |
defer resp.Body.Close() | |
byteArray, _ := ioutil.ReadAll(resp.Body) | |
fmt.Printf("log: %s", byteArray) | |
// レスポンスデータの生成 | |
w.Write(createResponsJson(&apiRequestResponse{Code: 2000, Message: "OK"})) | |
} | |
// DBを叩いてレスポンスを返す | |
func personHandler(w http.ResponseWriter, r *http.Request, env appEnvironment) { | |
// headerセット | |
w.Header().Set("Content-Type", "application/json; charset=utf-8") | |
// methodバリデーション | |
if r.Method != http.MethodGet { | |
w.WriteHeader(http.StatusMethodNotAllowed) | |
w.Write(createResponsJson(&apiRequestResponse{Code: 2001, Message: "Method not allowed."})) | |
return | |
} | |
// クエリパラメータ取得&バリデーションチェック | |
paramUser := r.URL.Query().Get("user") | |
if len(paramUser) == 0 { | |
w.WriteHeader(http.StatusBadRequest) | |
w.Write(createResponsJson(&apiRequestResponse{Code: 2002, Message: "user paramater not found."})) | |
return | |
} | |
// DBからデータを取得して結果をログに出力 | |
db, err := sql.Open("mysql", "root:"+env.password+"@/"+env.username) | |
if err != nil { | |
panic(err.Error()) | |
} | |
defer db.Close() | |
rows, err := db.Query("SELECT * FROM person") | |
if err != nil { | |
panic(err.Error()) | |
} | |
defer rows.Close() | |
for rows.Next() { | |
var person person | |
err := rows.Scan(&person.id, &person.name) | |
if err != nil { | |
panic(err.Error()) | |
} | |
fmt.Println(person.id, person.name) | |
} | |
err = rows.Err() | |
if err != nil { | |
panic(err.Error()) | |
} | |
// レスポンスデータの生成 | |
w.Write(createResponsJson(&apiRequestResponse{Code: 2000, Message: "OK"})) | |
} | |
// 都度Marshalしてエラーチェックするのは面倒なので | |
func createResponsJson(a *apiRequestResponse) []byte { | |
json, err := json.Marshal(*a) | |
if err != nil { | |
panic("json can not marshal.") | |
} | |
return json | |
} | |
// 環境変数を取得 | |
func getAppEnvironment() appEnvironment { | |
if len(os.Getenv("DB_USERNAME")) == 0 || len(os.Getenv("DB_PASSWORD")) == 0 { | |
panic("appEnvironment not setting.") | |
} | |
return appEnvironment{ | |
username: os.Getenv("DB_USERNAME"), | |
password: os.Getenv("DB_PASSWORD"), | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment