Go言語による
Webアプリの作り方
    2013/2/9 GDG Kobe



 Creative Commons Attribution 3.0 License
自己紹介
•   河本 泰孝 @kwmt27
•   車関連の仕事やってます。
•   androg.seesaa.net ブログ書いてます。
•   私とGo言語との関わり
    •   2011年のDevQuizで初めて触った
    •   2012年1月のGo言語勉強会に参加
    •   2012年4月の東海GTUGさんのGAE勉強会でGoを使った
    •   2012年8月のGDG神戸でGo言語のスライスについて発表
    •   2012年10月,2013年1月GDG名古屋のスタートGo#0,#1に
        参加
              Creative Commons Attribution 3.0 License
自己紹介
• 最近では公式サイトの
  • Writing Web Applications
  • Go Slices
 を翻訳してみたり。
 https://github.com/kwmt/
 golangwiki
      ↑↑ forkして一緒に翻訳しませんか?

            Creative Commons Attribution 3.0 License
自己紹介

前回は、Go Slicesについて発表させて
もらったので、今回は、
公式サイトのWriting Web Applications
を元に発表させて頂きます。



      Creative Commons Attribution 3.0 License
もくじ




Creative Commons Attribution 3.0 License
もくじ

1.Go言語の特徴&紹介
2.Go言語の基本
3.Webアプリ(wiki)を作成する
4.tips




         Creative Commons Attribution 3.0 License
Go言語の特徴&紹介



 Creative Commons Attribution 3.0 License
Go言語の特徴&紹介
オープンソース(BSDライセンス)
シンプルな構文
(文末のセミコロン不要など)
コンパイル言語
並列処理を言語レベルでサポート
(ゴルーチン)
GCによるメモリ管理
安全性が高い(ポインタ演算なし)
    Creative Commons Attribution 3.0 License
Go言語の特徴&紹介
Webアプリケーションを作るための豊富
な標準ライブラリ
Google App Engine for Go
*今回の話には出て来ません
*チュートリアルがまずは参考になると
思います。
https://developers.google.com/appengine/
docs/go/gettingstarted/
現時点のバージョン 1.0.3 License
    Creative Commons Attribution 3.0
Go言語の特徴&紹介
公式サイト http://golang.org
翻訳サイト http://golang.jp/
Go Playground http://play.golang.org/
A Tour of Go http://go-tour-jp.appspot.com
golang-nuts
http://groups.google.com/group/golang-nuts
golang-jp
https://groups.google.com/forum/#!forum/
golang-jp Creative Commons Attribution 3.0 License
Go言語の特徴&紹介
公式サイト http://golang.org
                                       Go version 1
翻訳サイト http://golang.jp/             未対応箇所あるので注意

Go Playground http://play.golang.org/
A Tour of Go http://go-tour-jp.appspot.com
golang-nuts
http://groups.google.com/group/golang-nuts
golang-jp
https://groups.google.com/forum/#!forum/
golang-jp Creative Commons Attribution 3.0 License
Go言語の特徴&紹介
go-wiki Articles
 http://code.google.com/p/go-wiki/wiki/
Articles
go-wiki Books
http://code.google.com/p/go-wiki/wiki/Books
Go1に対応した日本語の書籍
 プログラミング言語Goフレーズブック

 基礎からわかるGo言語

         Creative Commons Attribution 3.0 License
Go言語の特徴&紹介

なにより、ゴーファー君がかわいい
 (今日の一番大切なこと)




  Creative Commons Attribution 3.0 License
Go言語の基本



Creative Commons Attribution 3.0 License
基本1

package main

import "fmt"

func main() {
  var hello string = "Hello, 世界!"
  //hello := “Hello, 世界!”
  String(hello)
}
func String(s string) {
  fmt.Println(s)
}
               Creative Commons Attribution 3.0 License
package から始まります
                            基本1

package main

import "fmt"

func main() {
  var hello string = "Hello, 世界!"
  //hello := “Hello, 世界!”
  String(hello)
}
func String(s string) {
  fmt.Println(s)
}
               Creative Commons Attribution 3.0 License
基本1                 グループ化できます
                                                          import(
                    パッケージを読み込みます                            “fmt”
package main                                                “io/iouti.”
                                                          )
import "fmt"

func main() {
  var hello string = "Hello, 世界!"
  //hello := “Hello, 世界!”
  String(hello)
}
func String(s string) {
  fmt.Println(s)
}
               Creative Commons Attribution 3.0 License
基本1
                           main関数が最初に呼び
                                 出されます
package main
                  main関数があるpackageはmainでなければ
import "fmt"                     なりません
func main() {
  var hello string = "Hello, 世界!"
  //hello := “Hello, 世界!”
  String(hello)
}
func String(s string) {
  fmt.Println(s)
}
               Creative Commons Attribution 3.0 License
基本1

package main

import "fmt"
                                                            文末に
func main() {                                             セミコロン不要
  var hello string = "Hello, 世界!"
  //hello := “Hello, 世界!”
  String(hello)
}
func String(s string) {
  fmt.Println(s)
}
               Creative Commons Attribution 3.0 License
基本1

package main

import "fmt"

func main() {                   := だけで定義できる
  var hello string = "Hello, 世界!"
                                     (型推論)
  //hello := “Hello, 世界!”
  String(hello)
}
func String(s string) {
  fmt.Println(s)
}
               Creative Commons Attribution 3.0 License
基本1

package main

import "fmt"

func main() {
  var hello string = "Hello, 世界!"
  //hello := “Hello, 世界!”
  String(hello)                                  関数定義
}                                        プロトタイプ宣言不要
func String(s string) {
  fmt.Println(s)                                  値渡し
}
               Creative Commons Attribution 3.0 License
基本1

package main

import "fmt"

func main() {
  var hello string = "Hello, 世界!"
  //hello := “Hello, 世界!”
  String(hello)
}
                       パッケージ名.(ドット)関数名で
func String(s string) {
  fmt.Println(s)        パッケージの関数を呼び出す
}
               Creative Commons Attribution 3.0 License
基本2
func main() {
  for i:=0;i<10;i++{
    if i%2!=0 {
      fmt.Printf("%dは奇数n",i)
        }
    }
}




            Creative Commons Attribution 3.0 License
基本2
                                             for文、if文は()不要
                                             ループはfor文だけ
func main() {
  for i:=0;i<10;i++{
    if i%2!=0 {
      fmt.Printf("%dは奇数n",i)
        }
    }
}




            Creative Commons Attribution 3.0 License
基本2
                                             for文、if文は()不要
                                             ループはfor文だけ
func main() {
  for i:=0;i<10;i++{
    if i%2!=0 {
      fmt.Printf("%dは奇数n",i)              文法ではないですが
        }                                     $go fmt for.go
    }                                        で綺麗になります
}

                  func main() {
                  ! for i := 0; i < 10; i++ {
                  ! ! if i%2 != 0 {
                  ! ! ! fmt.Printf("%dは奇数n", i)
                   ! ! }
                   ! }
            Creative Commons Attribution 3.0 License
基本3

b := []string{“g”,”o”,”l”,”a”,”n”,”g”}


配列に似ていますが、これをスライスといいます。

b[2:] == []string{”l”,”a”,”n”,”g”}

上記の左辺ように書くと、右辺と同じ意味になります。
(スライスについては、前回の資料を参照ください。)




          Creative Commons Attribution 3.0 License
基本4
構造体
type MyData struct {
  name   string //名前
    Height int       //身長
}


メソッド

func (data *Mydata) SetName(name string) {
    data.name = name
}
                 Creative Commons Attribution 3.0 License
言い忘れてましたが、構造体に限らず、
                              基本4
                             変数名の最初の文字が
                     大文字と小文字に意味があります。
構造体
type MyData struct {
  name   string //名前
    Height int       //身長
}


メソッド

func (data *Mydata) SetName(name string) {
    data.name = name
}
                 Creative Commons Attribution 3.0 License
言い忘れてましたが、構造体に限らず、
                              基本4
                             変数名の最初の文字が
                     大文字と小文字に意味があります。
構造体
type MyData struct {                            javaで言うところ、
  name   string //名前
                                                大文字がpublicで、
    Height int       //身長
}                                             小文字がprivateです。


メソッド

func (data *Mydata) SetName(name string) {
    data.name = name
}
                 Creative Commons Attribution 3.0 License
基本4
構造体
type MyData struct {
  name   string //名前
    Height int       //身長
}                  関数の一種だが、特定の型
                   と関連づけることが可能
                    (thisとかselfとかはない)
メソッド

func (data *Mydata) SetName(name string) {
    data.name = name
}
                 Creative Commons Attribution 3.0 License
基本5

goを実行させるには?

$go build hoge.go
$./hoge

$go run hoge.go
(これはa.outが動く)

$pwd
fuga
$go build
$./fuga

            Creative Commons Attribution 3.0 License
Webアプリ(wiki)を作成する



   Creative Commons Attribution 3.0 License
ようやく本題


Webアプリとして、
wikiを作成して行きたいと思います。




     Creative Commons Attribution 3.0 License
wikiの仕様
http://localhost:8080/edit/sample




              Creative Commons Attribution 3.0 License
wikiの仕様
http://localhost:8080/edit/sample


 Editing sample




  Save




              Creative Commons Attribution 3.0 License
wikiの仕様
http://localhost:8080/edit/sample


 Editing sample
  sample body



  Save




              Creative Commons Attribution 3.0 License
wikiの仕様
http://localhost:8080/edit/sample


 Editing sample
  sample body



  Save
                           DB代わり
         /save/sample
          sample.txtを作成し、内容を保存
              Creative Commons Attribution 3.0 License
wikiの仕様
http://localhost:8080/edit/sample
                                             /view/sample

 Editing sample                            sample
  sample body                              [edit]
                                           sample body


  Save
                           DB代わり
                                                         リダイレクト
         /save/sample
          sample.txtを作成し、内容を保存
              Creative Commons Attribution 3.0 License
wikiの仕様
http://localhost:8080/edit/sample
                                             /view/sample

 Editing sample                            sample
  sample body                              [edit]
                                           sample body


  Save
                           DB代わり
                                                         リダイレクト
         /save/sample
          sample.txtを作成し、内容を保存
              Creative Commons Attribution 3.0 License
wikiの仕様
http://localhost:8080/edit/sample
                                            /view/sample
          Title                            Title
 Editing sample                            sample
  sample body                              [edit]
                                           sample body
          Body                                           Body

  Save
                           DB代わり
                                                         リダイレクト
         /save/sample
          sample.txtを作成し、内容を保存
              Creative Commons Attribution 3.0 License
HTTPサーバを開始
net/httpパッケージを使います。
package main

import "net/http"

func main() {
  http.ListenAndServe(":8080",nil)
}




           Creative Commons Attribution 3.0 License
HTTPサーバを開始
net/httpパッケージを使います。
package main

import "net/http"

func main() { ポート指定↓
  http.ListenAndServe(":8080",nil)
}




           Creative Commons Attribution 3.0 License
HTTPサーバを開始
net/httpパッケージを使います。
package main

import "net/http"

func main() { ポート指定↓           ↓nilを指定(通常)
  http.ListenAndServe(":8080",nil)
}




           Creative Commons Attribution 3.0 License
HTTPサーバを開始
net/httpパッケージを使います。
package main

import "net/http"

func main() { ポート指定↓           ↓nilを指定(通常)
  http.ListenAndServe(":8080",nil)
}         ↑↑でHTTPサーバーを開始します。



           Creative Commons Attribution 3.0 License
HTTPサーバを開始
net/httpパッケージを使います。
package main

import "net/http"

func main() { ポート指定↓           ↓nilを指定(通常)
  http.ListenAndServe(":8080",nil)
}         ↑↑でHTTPサーバーを開始します。



           Creative Commons Attribution 3.0 License
HTTPサーバを開始
net/httpパッケージを使います。
package main

import "net/http"

func main() { ポート指定↓           ↓nilを指定(通常)
  http.ListenAndServe(":8080",nil)
}         ↑↑でHTTPサーバーを開始します。

                                何も出力していないから。

           Creative Commons Attribution 3.0 License
ハンドラの登録
 webページに出力させるには、
 ハンドラを登録する必要があります。
package main

import "net/http"

func viewHandler(w http.ResponseWriter, r *http.Request){
  fmt.Fprintf(w, “Hello, %q”, r.URL.Path[1:])
}
func main() {
  http.HandleFunc(“/”, viewHandler)
  http.ListenAndServe(":8080",nil)
}

               Creative Commons Attribution 3.0 License
ハンドラの登録
 webページに出力させるには、
 ハンドラを登録する必要があります。
package main

import "net/http"

func viewHandler(w http.ResponseWriter, r *http.Request){
  fmt.Fprintf(w, “Hello, %q”, r.URL.Path[1:])
}
func main() { ↓”/”にviewHandlerを登録
  http.HandleFunc(“/”, viewHandler)
  http.ListenAndServe(":8080",nil)
}

               Creative Commons Attribution 3.0 License
http.Request
func viewHandler(w http.ResponseWriter, r *http.Request){
  fmt.Fprintf(w, “Hello, %q”, r.URL.Path)
}




              Creative Commons Attribution 3.0 License
http.Request
func viewHandler(w http.ResponseWriter, r *http.Request){
  fmt.Fprintf(w, “Hello, %q”, r.URL.Path)
}



type Request struct{
    Method string
    URL    *url.URL
    ...     ↑net/urlパッケージ
    Form   url.Values
    ...
}




              Creative Commons Attribution 3.0 License
http.Request
func viewHandler(w http.ResponseWriter, r *http.Request){
  fmt.Fprintf(w, “Hello, %q”, r.URL.Path)
}
                                        type URL struct {
                                            Scheme   string
type Request struct{                        Opaque   string
    Method string                           User     *Userinfo
    URL    *url.URL                         Host     string
    ...     ↑net/urlパッケージ                   Path     string
    Form   url.Values                       RawQuery string
    ...                                     Fragment string
}                                       }




              Creative Commons Attribution 3.0 License
http.Request
func viewHandler(w http.ResponseWriter, r *http.Request){
  fmt.Fprintf(w, “Hello, %q”, r.URL.Path)
}
                                        type URL struct {
                                            Scheme   string
type Request struct{                        Opaque   string
    Method string                           User     *Userinfo
    URL    *url.URL                         Host     string
    ...     ↑net/urlパッケージ                   Path     string
    Form   url.Values                       RawQuery string
    ...                                     Fragment string
}                                       }

  URLは次のような形を表現しています。
  scheme://[userinfo@]host/path[?query][#fragment]
              Creative Commons Attribution 3.0 License
ハンドラの登録
先ほどのviewHandlerを登録すると、次のようになります。




再掲
func viewHandler(w http.ResponseWriter, r *http.Request){
  fmt.Fprintf(w, “Hello, %q”, r.URL.Path[1:])
}
func main() {
  http.HandleFunc(“/” viewHandler)
  http.ListenAndServe(":8080",nil)
}             Creative Commons Attribution 3.0 License
データ構造の定義
さて、このwikiはeditページとviewページに
TitleとBodyを持っていますので、
構造体として保持しておくことにしましょう。

 type Page struct {
     Title string
     Body []byte
 }


         Creative Commons Attribution 3.0 License
テキストファイルへ保存
このPage構造体に対して、保存できるように
saveメソッド作成しましょう。

func (p *Page) save() error {                    パーミッション
  filename := p.Title + “.txt”     を8進数で指定↓
  return ioutil.WriteFile(filename, p.Body, 0600)
}                          ↑string   ↑[]byte


※io/ioutilパッケージのインポートが必要です。

            Creative Commons Attribution 3.0 License
テキストファイルから読み込み

次に保存したファイルを読み込めるような関数を作りましょう。

func loadPage(title string) (*Page, error) {
  filename := title + “.txt”
  body, err := ioutil.ReadFile(filename)
  if err != nil {        ↑ []byte、errorを返す
    return nil, err
  }
  return &Page{Title:title, Body:body}, nil
}
※io/ioutilパッケージのインポートが必要です。
            Creative Commons Attribution 3.0 License
HTMLを生成
http://localhost:8080/view/sample                 sample Title
にアクセスがあった時に、
                                                  [edit]
sample.txtを読み込み、
                                                  sample body Body
右図のように表示したい。




                 Creative Commons Attribution 3.0 License
HTMLを生成
http://localhost:8080/view/sample                 sample Title
にアクセスがあった時に、
                                                  [edit]
sample.txtを読み込み、
                                                  sample body Body
右図のように表示したい。

func viewHandler(w http.ResponseWriter, r *http.Request) {
! title := r.URL.Path[6:]
! p, _ := loadPage(title)
! fmt.Fprintf(w, "<h1>%s</h1><p>[<a href="/edit/%s
">edit</a>]</p><div>%s</div>",
        p.Title, p.Title, p.Body)
}
                 Creative Commons Attribution 3.0 License
HTMLを生成
http://localhost:8080/view/sample                 sample Title
にアクセスがあった時に、
                                                  [edit]
sample.txtを読み込み、
                                                  sample body Body
右図のように表示したい。

func viewHandler(w http.ResponseWriter, r *http.Request) {
! title := r.URL.Path[6:]
! p, _ := loadPage(title)
! fmt.Fprintf(w, "<h1>%s</h1><p>[<a href="/edit/%s
">edit</a>]</p><div>%s</div>",
        p.Title, p.Title, p.Body)
}
                 Creative Commons Attribution 3.0 License
HTMLを生成
http://localhost:8080/view/sample                 sample Title
にアクセスがあった時に、
                                                  [edit]
sample.txtを読み込み、
                                                  sample body Body
右図のように表示したい。
         このようなHTMLの
                        ハードコーディングはダサいですよね。
func viewHandler(w http.ResponseWriter, r *http.Request) {
                    いい方法がありますよ。奥さん
! title := r.URL.Path[6:]
! p, _ := loadPage(title)
! fmt.Fprintf(w, "<h1>%s</h1><p>[<a href="/edit/%s
">edit</a>]</p><div>%s</div>",
        p.Title, p.Title, p.Body)
}
                 Creative Commons Attribution 3.0 License
HTMLを生成
“text/template”パッケージを使います。




         Creative Commons Attribution 3.0 License
HTMLを生成
“text/template”パッケージを使います。

template : <p>Hello, {{.Title}}</p>




                 Creative Commons Attribution 3.0 License
HTMLを生成
“text/template”パッケージを使います。

template : <p>Hello, {{.Title}}</p>


   struct : Page{Title:”sample”}




                 Creative Commons Attribution 3.0 License
HTMLを生成
“text/template”パッケージを使います。

template : <p>Hello, {{.Title}}</p>
                                                    Hello, sample
   struct : Page{Title:”sample”}




                 Creative Commons Attribution 3.0 License
HTMLを生成
    “text/template”パッケージを使います。

    template : <p>Hello, {{.Title}}</p>
                                                        Hello, sample
       struct : Page{Title:”sample”}


func viewHandler(w *http.ResponseWriter, r *http.Request){
  ! title := r.URL.Path[6:]
!   p, _ := loadPage(title)

      t, _ := tempalte.ParseFiles(“view.html”)
      t.Execute(w, p)
}
                     Creative Commons Attribution 3.0 License
HTMLを生成
    “text/template”パッケージを使います。

    template : <p>Hello, {{.Title}}</p>
                                                        Hello, sample
       struct : Page{Title:”sample”}


func viewHandler(w *http.ResponseWriter, r *http.Request){
  ! title := r.URL.Path[6:]
!   p, _ := loadPage(title)

      t, _ := tempalte.ParseFiles(“view.html”)
      t.Execute(w, p)
}
                     Creative Commons Attribution 3.0 License
HTMLを生成
    “text/template”パッケージを使います。

    template : <p>Hello, {{.Title}}</p>
                                                        Hello, sample
       struct : Page{Title:”sample”}
                                          Template構造体を作成しパースします
func viewHandler(w *http.ResponseWriter, r *http.Request){
                                *Templateとerror を返します
  ! title := r.URL.Path[6:]
!   p, _ := loadPage(title)

      t, _ := tempalte.ParseFiles(“view.html”)
      t.Execute(w, p)
}
                     Creative Commons Attribution 3.0 License
HTMLを生成
    “text/template”パッケージを使います。

    template : <p>Hello, {{.Title}}</p>
                                                        Hello, sample
     struct : Page{Title:”sample”}
    パースされたテンプレート tを
                                          Template構造体を作成しパースします
         pに適用して、
func viewHandler(w *http.ResponseWriter, r *http.Request){
                                *Templateとerror を返します
  ! title := r.URL.Path[6:]
        wに出力します
!   p, _ := loadPage(title)

      t, _ := tempalte.ParseFiles(“view.html”)
      t.Execute(w, p)
}
                     Creative Commons Attribution 3.0 License
HTMLを生成
    “text/template”パッケージを使います。

    template : <p>Hello, {{.Title}}</p>
                                                Hello, sample
     struct : Page{Title:”sample”}
    パースされたテンプレート tを
                                          Template構造体を作成しパースします
         pに適用して、
func viewHandler(w *http.ResponseWriter, r *http.Request){
                                *Templateとerror を返します
  ! title := r.URL.Path[6:]
        wに出力します
!   p, _ := loadPage(title)

      t, _ := tempalte.ParseFiles(“view.html”)
      t.Execute(w, p)
}                                         先ほどハードコーディングされた
                                      HTMLを別ファイルに書く(あとで)
                     Creative Commons Attribution 3.0 License
HTMLを生成

公式ページを見ると”html/template”というのもありますが、
“text/template” と同じインターフェースを持ちます。
違いは、”html/template”は攻撃に強いセキュアな
HTMLを生成します。
ただし、HTMLに書いたコメントが消されます(´;ω;`)




          Creative Commons Attribution 3.0 License
HTMLを生成
view.htmlを次のようにします。




        Creative Commons Attribution 3.0 License
HTMLを生成
view.htmlを次のようにします。

<h1>{{.Title}}</h1>
<p>[<a href="/edit/{{.Title}}">edit</a>]</p>
<div>{{printf "%s" .Body}}</div>




           Creative Commons Attribution 3.0 License
HTMLを生成
view.htmlを次のようにします。

<h1>{{.Title}}</h1>
<p>[<a href="/edit/{{.Title}}">edit</a>]</p>
<div>{{printf "%s" .Body}}</div>



 これは、 .Bodyが[]byteであるため、stringにして表示しています。
        http://golang.org/pkg/text/template/#hdr-Functions




            Creative Commons Attribution 3.0 License
HTMLを生成                                /edit/sample
                                         Editing sample

次にeditページを作成します。
edit.htmlを次のようにしましょう。


                                           Save




         Creative Commons Attribution 3.0 License
HTMLを生成                                    /edit/sample
                                              Editing sample

次にeditページを作成します。
edit.htmlを次のようにしましょう。


<h1>Editing {{.Title}}</h1>                     Save

<form action="/save/{{.Title}}" method="POST">
<div><textarea name="body" rows="20" cols="80">
{{printf "%s" .Body}}
</textarea></div>
<div><input type="submit" value="Save"></div>
</form>
              Creative Commons Attribution 3.0 License
HTMLを生成



次に、editページも同様に作成しましょう。




   Creative Commons Attribution 3.0 License
HTMLを生成
editHandlerを次のようにします。
http.HandleFunc(“/edit/”, editHandler) ←ハンドラ登録も忘れずに

func editHandler(w *http.ResponseWriter,r *http.Request){
    title := r.URL.Path[6:]
    p, err := loadPage(title)
    if err != nil {
        p = &Page{Title: title} //空のPage構造体を作成
    }
    t, _ := template.ParseFiles(“edit.html”)
    t.Execute(w, p)
}



             Creative Commons Attribution 3.0 License
どこまでできた?
http://localhost:8080/edit/sample




              Creative Commons Attribution 3.0 License
どこまでできた?
http://localhost:8080/edit/sample


 Editing sample




  Save




              Creative Commons Attribution 3.0 License
どこまでできた?
http://localhost:8080/edit/sample


 Editing sample
  sample body



  Save




              Creative Commons Attribution 3.0 License
どこまでできた?
http://localhost:8080/edit/sample
                          editHandler

 Editing sample
  sample body



  Save


         /save/sample
          sample.txtを作成し、内容を保存
              Creative Commons Attribution 3.0 License
どこまでできた?
http://localhost:8080/edit/sample
                                             /view/sample
                          editHandler

 Editing sample                            sample
  sample body                              [edit]
                                           sample body


  Save


         /save/sample
          sample.txtを作成し、内容を保存
              Creative Commons Attribution 3.0 License
どこまでできた?
http://localhost:8080/edit/sample
                                             /view/sample
                          editHandler

 Editing sample                            sample
  sample body                              [edit]
                                           sample body


  Save


         /save/sample
          sample.txtを作成し、内容を保存
              Creative Commons Attribution 3.0 License
どこまでできた?
http://localhost:8080/edit/sample
                                            /view/sample
                          editHandler
          Title                            Title
 Editing sample           edit.html        sample    viewHandler
                                                      view.html
  sample body                              [edit]
                                           sample body
          Body                                           Body

  Save


         /save/sample
          sample.txtを作成し、内容を保存
              Creative Commons Attribution 3.0 License
どこまでできた?
http://localhost:8080/edit/sample
                                            /view/sample
                          editHandler
          Title                            Title
 Editing sample           edit.html        sample    viewHandler
                                                      view.html
  sample body                              [edit]
                                           sample body
          Body                                           Body

  Save


         /save/sample
          sample.txtを作成し、内容を保存
              Creative Commons Attribution 3.0 License
saveHandlerを作成
edit.htmlを次のようにします。

http.HandleFunc(“/save/”, saveHandler)

func saveHandler(w http.ResponseWriter, r *http.Request) {
  title := r.URL.Path[6:]
  body := r.FormValue("body")
  p := &Page{Title:title, Body:[]byte(body)}
  p.save()
  http.Redirect(w, r, "/view/" + title, http.StatusFound)
}




              Creative Commons Attribution 3.0 License
saveHandlerを作成
テキストエリアに
edit.htmlを次のようにします。
入力した内容(string型)を取得できる

http.HandleFunc(“/save/”, saveHandler)

func saveHandler(w http.ResponseWriter, r *http.Request) {
  title := r.URL.Path[6:]
  body := r.FormValue("body")
  p := &Page{Title:title, Body:[]byte(body)}
  p.save()
  http.Redirect(w, r, "/view/" + title, http.StatusFound)
}




              Creative Commons Attribution 3.0 License
saveHandlerを作成
テキストエリアに
edit.htmlを次のようにします。
入力した内容(string型)を取得できる

http.HandleFunc(“/save/”, saveHandler)

func saveHandler(w http.ResponseWriter, r *http.Request) {
  title := r.URL.Path[6:]
  body := r.FormValue("body")
  p := &Page{Title:title, Body:[]byte(body)}
  p.save()
  http.Redirect(w, r, "/view/" + title, http.StatusFound)
}
   ステータスコードを付与してリダイレクトする
   ここでは“/view/” + title にリダイレクト
              Creative Commons Attribution 3.0 License
saveHandlerを作成
テキストエリアに
edit.htmlを次のようにします。
入力した内容(string型)を取得できる

                             http.StatusMovedPermanently = 301
http.HandleFunc(“/save/”, saveHandler)
                             http.StatusFound = 302
                             http.StatusSeeOther = 303
func saveHandler(w http.ResponseWriter, r *http.Request) {
  title := r.URL.Path[6:]    http.StatusTemporaryRedirect = 307
    body := r.FormValue("body")
    p := &Page{Title:title, Body:[]byte(body)}
    p.save()
    http.Redirect(w, r, "/view/" + title, http.StatusFound)
}
     ステータスコードを付与してリダイレクトする
     ここでは“/view/” + title にリダイレクト
                Creative Commons Attribution 3.0 License
基本的なwikiは完成
http://localhost:8080/edit/sample




              Creative Commons Attribution 3.0 License
基本的なwikiは完成
http://localhost:8080/edit/sample


 Editing sample




  Save




              Creative Commons Attribution 3.0 License
基本的なwikiは完成
http://localhost:8080/edit/sample


 Editing sample
  sample body



  Save




              Creative Commons Attribution 3.0 License
基本的なwikiは完成
http://localhost:8080/edit/sample
                          editHandler

 Editing sample
  sample body



  Save


         /save/sample
          sample.txtを作成し、内容を保存
              Creative Commons Attribution 3.0 License
基本的なwikiは完成
http://localhost:8080/edit/sample
                                             /view/sample
                          editHandler

 Editing sample                            sample
  sample body                              [edit]
                                           sample body


  Save


         /save/sample
          sample.txtを作成し、内容を保存
              Creative Commons Attribution 3.0 License
基本的なwikiは完成
http://localhost:8080/edit/sample
                                             /view/sample
                          editHandler

 Editing sample                            sample
  sample body                              [edit]
                                           sample body


  Save


         /save/sample
          sample.txtを作成し、内容を保存
              Creative Commons Attribution 3.0 License
基本的なwikiは完成
http://localhost:8080/edit/sample
                                            /view/sample
                          editHandler
          Title                            Title
 Editing sample           edit.html        sample    viewHandler
                                                      view.html
  sample body                              [edit]
                                           sample body
          Body                                           Body

  Save


         /save/sample
          sample.txtを作成し、内容を保存
              Creative Commons Attribution 3.0 License
基本的なwikiは完成
http://localhost:8080/edit/sample
                                            /view/sample
                          editHandler
          Title                            Title
 Editing sample           edit.html        sample    viewHandler
                                                      view.html
  sample body                              [edit]
                                           sample body
          Body            saveHandler
                                                         Body

  Save


         /save/sample
          sample.txtを作成し、内容を保存
              Creative Commons Attribution 3.0 License
基本的なwikiは完成
エラー処理など、殆どやってないので、
イケてないところが多く残っていますが、
wikiの基本機能は完成です。

Writing Web Applicationでは、regexpパッケージ使用して
入力チェックしたり、クロージャを使用したりあります
が、詳しくはWebを参照ください。



          Creative Commons Attribution 3.0 License
tips



Creative Commons Attribution 3.0 License
GET、POST
net/http パッケージ

func Get(url string) (resp *Response, err error)

例 res, _ := http.Get("http://www.google.com/robots.txt")
  body, _ := iouti.ReadAll(res.Body)
  res.Body.Close()

func Post(url string, bodyType string, body io.Reader)
(resp *Response, err error)


               Creative Commons Attribution 3.0 License
XML、JSON

   encoding/xml
                 パッケージが使用できます。
   encoding/json




例 http://play.golang.org/p/ADbOOeCVCn
                     Creative Commons Attribution 3.0 License
XML、JSON

   encoding/xml
                 パッケージが使用できます。
   encoding/json



                                          xml
        構造体
                                         json




例 http://play.golang.org/p/ADbOOeCVCn
                     Creative Commons Attribution 3.0 License
XML、JSON

   encoding/xml
                 パッケージが使用できます。
   encoding/json

                    Marshal(v interface{}) (data []byte, error)
                                          xml
        構造体
                                         json

                    Unmarshal(data []byte, v interface{}) error


例 http://play.golang.org/p/ADbOOeCVCn
                     Creative Commons Attribution 3.0 License
XML、JSON

   encoding/xml
                 パッケージが使用できます。
   encoding/json

                    Marshal(v interface{}) (data []byte, error)
                                          xml
        構造体                                              同じI/F
                                         json

                    Unmarshal(data []byte, v interface{}) error


例 http://play.golang.org/p/ADbOOeCVCn
                     Creative Commons Attribution 3.0 License
XML、JSON

   encoding/xml
                 パッケージが使用できます。
   encoding/json

                    Marshal(v interface{}) (data []byte, error)
                                          xml
        構造体                                              同じI/F
                                         json

                    Unmarshal(data []byte, v interface{}) error
                                                 ポインタじゃないと

例 http://play.golang.org/p/ADbOOeCVCn                 怒られます
                     Creative Commons Attribution 3.0 License
サーバ上で Javascriptを使う

http.Handle(“/js/”,
      http.StripPrefix(“/js/”, http.FileServer(http.Dir(“js”))))




               Creative Commons Attribution 3.0 License
template
ファイルを分けることも可能
<!doctype html>
<html>
<head></head>
<body>
{{template “content” .}}
</body>
</html>

{{define “content”}}{{.Titile}}{{end}}


              Creative Commons Attribution 3.0 License
データベースのドライバ




SQL database drivers

             Creative Commons Attribution 3.0 License
FastCGI
package main
import (
! "fmt"
! "net"
! "net/http"
! "net/http/fcgi"
)
func main() {
! mux := http.NewServeMux()
! mux.HandleFunc("/", index)
! l, _ := net.Listen("tcp", ":9000")
! fcgi.Serve(l, mux)
}
func index(w http.ResponseWriter, r *http.Request) {
! fmt.Fprintf(w, "hello,FastCGI!")
}

          Creative Commons Attribution 3.0 License
FastCGI
package main
import (
! "fmt"
! "net"
! "net/http"
! "net/http/fcgi"
)
func main() {
! mux := http.NewServeMux()
! mux.HandleFunc("/", index)
! l, _ := net.Listen("tcp", ":9000")
! fcgi.Serve(l, mux)
}
func index(w http.ResponseWriter, r *http.Request) {
! fmt.Fprintf(w, "hello,FastCGI!")
}
                                                     nginx上で動きます
          Creative Commons Attribution 3.0 License
websocket
websocketのパッケージはGo 1になって標準パッケージでは
なくなりましたが、別のリポジトリに残ってます。
“code.google.com/p/go.net/websocket”

下記のブログにwebsocketを使ってチャット作った動画が上
がっています。
http://u.hinoichi.net/2012/12/14/websocketを使ってみた-with-go言語/


動画
http://www.youtube.com/watch?
feature=player_embedded&v=ekXCCIxN3gg
               Creative Commons Attribution 3.0 License
以上、つたない説明でしたが
Go言語でWebアプリを作る
足がかりなれば幸いです。




  Creative Commons Attribution 3.0 License
ご清聴ありがとうございました




   Creative Commons Attribution 3.0 License

Go言語によるwebアプリの作り方