2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Goハンズオン】シンプルなWebアプリケーションを作ってみよう

Posted at

この記事では、Go言語を用いてシンプルなWebアプリケーションを構築する方法をステップバイステップで解説します。
公式チュートリアルをベースにしているため、Goの基本的なWebサーバーやテンプレート、ファイル入出力の扱い方を学ぶことができます。

1. はじめに

今回作成するWebアプリケーションは、以下の機能を持っています。

  • ページの閲覧
  • ページの編集
  • ページの保存

ユーザーはURLにページ名を指定することで、既存ページを閲覧または編集でき、編集結果はテキストファイルとして保存されます。

2. 開発環境の準備

  • Goのインストール
    最新版のGoがインストールされていることを確認してください。

    go version
    
  • エディタの用意
    お好きなエディタ(VSCode、GoLand、vimなど)を使用してください。

3. プロジェクト構成

以下のようなファイル構成で進めます。

wiki/
├── wiki.go      // メインのGoコード
├── edit.html    // 編集用テンプレート
└── view.html    // 閲覧用テンプレート

4. Goコードの実装

まずは、wiki.go を作成します。コード内では、HTTPハンドラー、テンプレートのレンダリング、ファイルの読み書きなどを実装します。

package main

import (
	"html/template"
	"net/http"
	"os"
	"regexp"
)

// PageはWikiの各ページを表します
type Page struct {
	Title string
	Body  []byte
}

// ページ内容をファイルに保存する
func (p *Page) save() error {
	filename := p.Title + ".txt"
	return os.WriteFile(filename, p.Body, 0600)
}

// ファイルからページ内容を読み込む
func loadPage(title string) (*Page, error) {
	filename := title + ".txt"
	body, err := os.ReadFile(filename)
	if err != nil {
		return nil, err
	}
	return &Page{Title: title, Body: body}, nil
}

// テンプレートのパース(edit.html, view.html)
var templates = template.Must(template.ParseFiles("edit.html", "view.html"))

// 指定のテンプレートにデータを適用してレンダリングする
func renderTemplate(w http.ResponseWriter, tmpl string, p *Page) {
	err := templates.ExecuteTemplate(w, tmpl+".html", p)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
}

// URLパスの正規表現(ページ名は英数字のみ)
var validPath = regexp.MustCompile("^/(edit|save|view)/([a-zA-Z0-9]+)$")

// ハンドラーをラップし、URLからタイトル部分を抽出する
func makeHandler(fn func(http.ResponseWriter, *http.Request, string)) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		m := validPath.FindStringSubmatch(r.URL.Path)
		if m == nil {
			http.NotFound(w, r)
			return
		}
		fn(w, r, m[2])
	}
}

// ページの閲覧
func viewHandler(w http.ResponseWriter, r *http.Request, title string) {
	p, err := loadPage(title)
	if err != nil {
		http.Redirect(w, r, "/edit/"+title, http.StatusFound)
		return
	}
	renderTemplate(w, "view", p)
}

// ページの編集
func editHandler(w http.ResponseWriter, r *http.Request, title string) {
	p, err := loadPage(title)
	if err != nil {
		p = &Page{Title: title}
	}
	renderTemplate(w, "edit", p)
}

// ページの保存
func saveHandler(w http.ResponseWriter, r *http.Request, title string) {
	body := r.FormValue("body")
	p := &Page{Title: title, Body: []byte(body)}
	err := p.save()
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	http.Redirect(w, r, "/view/"+title, http.StatusFound)
}

func main() {
	http.HandleFunc("/view/", makeHandler(viewHandler))
	http.HandleFunc("/edit/", makeHandler(editHandler))
	http.HandleFunc("/save/", makeHandler(saveHandler))
	http.ListenAndServe(":8080", nil)
}

コード解説

  • Page構造体
    Wikiの各ページを TitleBody で表現しています。

  • save/load関数
    ページ内容をテキストファイルとして保存・読み込みするための関数です。

  • テンプレート処理
    html/template を利用して、edit.htmlview.html をパースし、データをレンダリングしています。

  • URLパスの検証
    正規表現でURLパスを検証し、/edit/, /save/, /view/ にマッチした場合のみ処理を行います。

  • ハンドラーの実装
    各ハンドラー(view, edit, save)は、ページの読み込みや編集・保存の処理を行い、必要に応じてリダイレクトを実施します。

5. テンプレートファイルの作成

edit.html

<html>
  <head>
    <title>Editing {{.Title}}</title>
  </head>
  <body>
    <h1>Editing {{.Title}}</h1>
    <form action="/save/{{.Title}}" method="POST">
      <textarea name="body" rows="20" cols="80">{{printf "%s" .Body}}</textarea><br>
      <input type="submit" value="Save">
    </form>
  </body>
</html>

view.html

<html>
  <head>
    <title>{{.Title}}</title>
  </head>
  <body>
    <h1>{{.Title}}</h1>
    <div>{{printf "%s" .Body}}</div>
    <br>
    <a href="/edit/{{.Title}}">Edit</a>
  </body>
</html>

テンプレートでは、{{.Title}}{{printf "%s" .Body}} を使って、Goコードで作成した Page 構造体のフィールドを表示しています。

6. アプリケーションの起動と動作確認

  1. プロジェクトディレクトリに移動し、上記ファイルを作成します。

  2. 以下のコマンドでアプリケーションを起動します。

    go run wiki.go
    
  3. ブラウザで http://localhost:8080/view/FrontPage にアクセスすると、まずは編集画面にリダイレクトされます。

  4. テキストを入力して「Save」ボタンを押すと、ファイルが作成され、編集した内容が表示されます。

7. まとめ

本記事では、Go言語の公式Wikiチュートリアルをもとに、シンプルなWebアプリケーションの実装方法を解説しました。
今回のハンズオンで学んだポイントは以下の通りです。

  • Goの標準パッケージを使ったWebサーバーの構築方法
  • テンプレートを利用した動的HTMLの生成
  • 正規表現によるURLパスの検証
  • ファイルシステムを利用した簡易データの永続化

今後、ユーザー認証やより高度なデータストレージ(例:データベース)などを組み合わせることで、さらに実用的なWebアプリケーションへと拡張していくことが可能です。

ぜひ、今回のハンズオンをベースに、自分なりの改良や拡張に挑戦してみてください!

参考: Go公式Wikiチュートリアル

2
1
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
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?