なるべくGoのパッケージを使わないで、RESTサーバとクライアントを作って、JSONのデータ送受信してみる
サーバ側 loc_rest_server.go というファイル名で保存して、
>go run loc_rest_server.go
で起動
package main
import (
"context"
"encoding/json"
"fmt"
"log"
"net/http"
"os"
"time"
"github.com/gorilla/mux"
)
/*
type GetLoc struct {
Message string `json:"message"`
Name string `json:"name"`
}
*/
/*
// GetLoc GetLoc
type GetLoc struct {
ID int64 `json:"id"`
Lat float64 `json:"lat"`
Lng float64 `json:"lng"`
//Address string `json:"address"`
}
*/
// GetLoc GetLoc
type GetLoc struct {
ID string `json:"id"`
Lat string `json:"lat"`
Lng string `json:"lng"`
//Address string `json:"address"`
}
// ErrorResponse error response
type ErrorResponse struct {
Code int `json:"code"`
Message string `json:"message"`
}
// locService loc service
func locService(ctx context.Context, number string, tm time.Time) (*GetLoc, error) {
if number == "1" {
return &GetLoc{
ID: number,
Lat: "35.653976",
Lng: "139.796842",
}, nil
}
if number == "2" {
return &GetLoc{
ID: number,
Lat: "35.653758",
Lng: "139.794192",
}, nil
}
return nil, nil
}
// AppHandler application handler adaptor
type AppHandler struct {
h func(http.ResponseWriter, *http.Request) (int, interface{}, error)
}
func (a AppHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
encoder := json.NewEncoder(w)
status, res, err := a.h(w, r)
if err != nil {
log.Printf("error: %s", err)
w.WriteHeader(status)
encoder.Encode(res)
return
}
w.WriteHeader(status)
encoder.Encode(res)
return
}
/*
// GetLoc GetLoc
func (app *App) GetLoc(w http.ResponseWriter, r *http.Request) (int, interface{}, error) {
res, err := locService(r.Context(), "", time.Now())
if err != nil {
app.Logger.Printf("error: %s", err)
e := ErrorResponse{
Code: http.StatusInternalServerError,
Message: "something went wrong",
}
return http.StatusInternalServerError, e, err
}
app.Logger.Printf("ok: %v", res)
return http.StatusOK, res, nil
}
*/
// GetLocWithNumber GetLoc with number
func (app *App) GetLocWithNumber(w http.ResponseWriter, r *http.Request) (int, interface{}, error) {
val := mux.Vars(r)
//res, err := locService(r.Context(), val["id"], time.Now())
res, err := locService(r.Context(), val["id"], time.Now())
if err != nil {
app.Logger.Printf("error: %s", err)
e := ErrorResponse{
Code: http.StatusInternalServerError,
Message: "something went wrong",
}
return http.StatusInternalServerError, e, err
}
app.Logger.Printf("ok: %v", res)
return http.StatusOK, res, nil
}
// App application
type App struct {
Host string
Name string
Logger *log.Logger
}
func main() {
host, err := os.Hostname()
if err != nil {
log.Fatal(err)
}
app := App{
Name: "my-service",
Host: host,
Logger: log.New(os.Stdout, fmt.Sprintf("[host=%s] ", host), log.LstdFlags),
}
// for gorilla/mux
router := mux.NewRouter()
r := router.PathPrefix("/api").Subrouter()
//r.Methods("GET").Path("/loc").Handler(AppHandler{h: app.GetLoc})
//r.Methods("GET").Path("/loc/staticName").Handler(AppHandler{h: app.GetLoc})
r.Methods("GET").Path("/loc/{id}").Handler(AppHandler{h: app.GetLocWithNumber})
if err := http.ListenAndServe(":8080", router); err != nil {
log.Fatal(err)
}
}
クライアント側
main.go で保存して、
>go run main.go
で起動
参考とさせて頂いたページ「Goでhttpリクエストを送信する方法」
package main
import (
"fmt"
"io/ioutil"
"net/http"
)
func main() {
//url := "http://google.co.jp"
url := "http://localhost:8080/api/loc/2"
resp, _ := http.Get(url)
defer resp.Body.Close()
byteArray, _ := ioutil.ReadAll(resp.Body)
fmt.Println(string(byteArray)) // htmlをstringで取得
}
動作結果
>go run main.go
{"id":"2","lat":"35.653758","lng":"139.794192"}
JSONで展開するにはどうしたらいいかな?
参考にさせて頂いたのは「goでjson apiを叩く」
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
)
// GetLoc GetLoc
type GetLoc struct {
ID string `json:"id"`
Lat string `json:"lat"`
Lng string `json:"lng"`
//Address string `json:"address"`
}
func main() {
//url := "http://google.co.jp"
url := "http://localhost:8080/api/loc/2"
resp, _ := http.Get(url)
defer resp.Body.Close()
/*
byteArray, _ := ioutil.ReadAll(resp.Body)
fmt.Println(string(byteArray)) // htmlをstringで取得
*/
var d GetLoc
fmt.Printf("======Body (use json.Unmarshal)======\n")
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
err = json.Unmarshal(body, &d)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%v\n", d)
fmt.Printf("ID:%v\n", d.ID)
fmt.Printf("Lat:%v\n", d.Lat)
fmt.Printf("Lng:%v\n", d.Lng)
}
出力結果
>go run main.go
======Body (use json.Unmarshal)======
{2 35.653758 139.794192}
ID:2
Lat:35.653758
Lng:139.794192