LoginSignup
20
26

More than 5 years have passed since last update.

Go言語のWebフレームワーク「Echo」を使ってみる ②(リクエストパラメータの扱い)

Last updated at Posted at 2017-06-04

すべての記事の一覧はこちら。
Go言語でWebサイトを作ってみる:目次
http://qiita.com/y_ussie/items/8fcc3077274449478bc9

前回のHello World篇 http://qiita.com/y_ussie/items/ca8dc5e423eec318a436 の続きです。

今回はリクエストパラメータの取得を試してみます。
前回のHello World篇では「Hello World」をHTMLとJSONで出力しましたが、この文字列の「World」の部分をリクエストパラメータで渡すようにしてみます。

パラメータを受け取る方法については、以下の3種に対応します。

  • クエリーパラメータ(GET)
  • フォーム(POST)
  • JSON(POST)

やりたいこと

以下のリクエストを処理する。

GET /hello?greetingto=xxx

クエリーパラメータで受け取った「greetingto」パラメータをテンプレートに埋め込み、
Hello xxx!
の文字列をHTMLで出力する。

GET /api/hello?greetingto=xxx

クエリーパラメータで受け取った「greetingto」パラメータより、
以下のJSONを返す。

{"hello": "xxx"}

GET /hello_form

以下のフォームを出力する。

1.png

HTMLテンプレートは以下のようなコード。

template/hello_form.html
{{define "content"}}
<form action="/hello" method="POST">
    <label for="greetingto">Greeting To: </label>
    <input type="text" id="greetingto" name="greetingto" />
    <input type="submit" />
</form>
{{end}}

POST /hello

hello_formよりPOSTされた「greetingto」パラメータをテンプレートに埋め込み、
Hello xxx!
の文字列をHTMLで出力する。

POST /api/hello

POSTされた以下のJSON

{"greetingto": "xxx"}

より取得した「greetingto」パラメータより、
以下のJSONを返す。

{"hello": "xxx"}

前回のコードに追加してみた。

main.go
package main

import (
    "html/template"
    "io"
    "net/http"

    "github.com/labstack/echo"
    "github.com/labstack/echo/middleware"
)

// レイアウト適用済のテンプレートを保存するmap
var templates map[string]*template.Template

// Template はHTMLテンプレートを利用するためのRenderer Interfaceです。
type Template struct {
}

// Render はHTMLテンプレートにデータを埋め込んだ結果をWriterに書き込みます。
func (t *Template) Render(w io.Writer, name string, data interface{}, c echo.Context) error {
    return templates[name].ExecuteTemplate(w, "layout.html", data)
}

func main() {
    // Echoのインスタンスを生成
    e := echo.New()

    // テンプレートを利用するためのRendererの設定
    t := &Template{}
    e.Renderer = t

    // ミドルウェアを設定
    e.Use(middleware.Logger())
    e.Use(middleware.Recover())

    // 静的ファイルのパスを設定
    e.Static("/public/css/", "./public/css")
    e.Static("/public/js/", "./public/js/")
    e.Static("/public/img/", "./public/img/")

    // 各ルーティングに対するハンドラを設定
    e.GET("/", HandleIndexGet)
    e.GET("/hello", HandleHelloGet)
    e.POST("/hello", HandleHelloPost)
    e.GET("/hello_form", HandleHelloFormGet)
    e.GET("/api/hello", HandleAPIHelloGet)
    e.POST("/api/hello", HandleAPIHelloPost)

    // サーバーを開始
    e.Logger.Fatal(e.Start(":3000"))
}

// 初期化を行います。
func init() {
    loadTemplates()
}

// 各HTMLテンプレートに共通レイアウトを適用した結果を保存します(初期化時に実行)。
func loadTemplates() {
    var baseTemplate = "templates/layout.html"
    templates = make(map[string]*template.Template)
    templates["hello"] = template.Must(
        template.ParseFiles(baseTemplate, "templates/hello.html"))
    templates["hello_form"] = template.Must(
        template.ParseFiles(baseTemplate, "templates/hello_form.html"))
}

// HandleIndexGet は Index のGet時のHTMLデータ生成処理を行います。
func HandleIndexGet(c echo.Context) error {
    return c.Render(http.StatusOK, "hello", "world")
}

// HandleHelloGet は /hello のGet時のHTMLデータ生成処理を行います。
func HandleHelloGet(c echo.Context) error {
    greetingto := c.QueryParam("greetingto")
    return c.Render(http.StatusOK, "hello", greetingto)
}

// HandleHelloPost は /hello のPost時のHTMLデータ生成処理を行います。
func HandleHelloPost(c echo.Context) error {
    greetingto := c.FormValue("greetingto")
    return c.Render(http.StatusOK, "hello", greetingto)
}

// HandleHelloFormGet は /hello_form のGet時のHTMLデータ生成処理を行います。
func HandleHelloFormGet(c echo.Context) error {
    return c.Render(http.StatusOK, "hello_form", nil)
}

// HandleAPIHelloGet は /api/hello のGet時のJSONデータ生成処理を行います。
func HandleAPIHelloGet(c echo.Context) error {
    greetingto := c.QueryParam("greetingto")
    return c.JSON(http.StatusOK, map[string]interface{}{"hello": greetingto})
}

// HelloParam は /api/hello が受けとるJSONパラメータを定義します。
type HelloParam struct {
    GreetingTo string `json:"greetingto"`
}

// HandleAPIHelloPost は /api/hello のPost時のJSONデータ生成処理を行います。
func HandleAPIHelloPost(c echo.Context) error {
    param := new(HelloParam)
    if err := c.Bind(param); err != nil {
        return err
    }
    return c.JSON(http.StatusOK, map[string]interface{}{"hello": param.GreetingTo})
}

前回のコードをベースに今回の機能を追加してみました。
主に増えているのはフォームの表示のハンドラ HandleHelloFormGet() とPOST用のハンドラ
HandleHelloPost(), HandleAPIHelloPost() です。

HandleHelloGet() と HandleAPIHelloGet() には、クエリーパラメータの処理が増えています。
クエリーパラメータは echo.Context#QueryParam() で取得できます。

HandleHelloPost() は、フォームパラメータのPOSTを受ける処理です。
フォームパラメータは、echo.Context#FormValue() で取得できます。

HandleAPIHelloPost() は、JSONのPOSTを受ける処理です。
POSTされたJSONパラメータを取得するには、まずJSONを受け取るための構造体を用意しておき、構造体を
echo.Context#Bind() することで構造体のメンバとして取得できます。

実行結果

POST /hello

2.png

POST /api/hello

3.png

次回予定

Cookieでも試してみますか。。

20
26
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
20
26