Help us understand the problem. What is going on with this article?

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

More than 3 years have passed since last update.

すべての記事の一覧はこちら。
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でも試してみますか。。

y_ussie
しがないSEです。 仕事ではC++ばっかり書いてます。 趣味プログラミングでは最近Goに傾倒しています。 ハードウェアも少し。 https://twitter.com/y_ussie
https://ussie.net
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away