0
0

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アプリをスマホから使えるようにした(renderでデプロイした)

Last updated at Posted at 2025-12-13

ちょっとしたプレーンテキストをpcとスマホ(iphone)間で共有しようとしたときに、以前まではLINEやメモ帳(icloud経由共有)やgmailの下書きに保存、notionなどの方法を使っていました。
しかしLINEはPCで立ち上げるのが面倒だし、icloudのメモ帳は立ち上がりが遅かったりプレーンテキストじゃなかったりするし、gmailの下書きも最近(?)プレーンテキストじゃなくなったりと何かと微妙な点を感じていました。notionはかなり良かったですが。
そこで、簡単なプレーンテキストの共有くらいなら無課金でできないか?と考えました。
まず、webアプリユーザーが入力した情報をサーバー側に保存する必要があるので、javascriptでは完結しません。ですので前回紹介したgithub pagesは使えません。
いろいろ探したところ、renderというサービスを見つけました。本記事ではgoの自作webアプリをrenderでデプロイして動かすところまでを説明します。
Go, fiberの書き方/使い方というよりもデプロイのところに集中して説明します。

なお、javascriptで完結する場合はgithub pagesのほうが簡単です。前回の記事をご覧ください。

どういう人/場合に役立つか

  • 簡単なwebアプリをとにかく作って動かしてみたい人
  • ネットワーク/web技術の理解のための第一歩を踏み出したいとき

go+renderでwebアプリ作成

まず、go+renderでwebアプリを作ります。
私はこの時初めてgoを触ったので、ざっくりですが環境構築の手順も書いておきます。

  • 公式サイトからインストーラーをダウンロードし、インストール
  • VSCodeの拡張機能を入れる

次に、webアプリを作ります。こちらもざっくり書いておきます。

  • githubリポジトリを作る。(プライベートリポジトリ可)
  • プロジェクトフォルダを作り、ターミナルでgo mod init (リポジトリurl)を実行
  • プログラムを書く
  • go mod tidyを実行
書いたプログラム
フォルダ配置
プロジェクト/
├views/
│└index.html
├main.go
├go.mod

go.modはgo mod initを実行すると自動でできます。

package main

import(
	"database/sql"
	"fmt"
	"log"

	"github.com/gofiber/fiber/v2"
	"github.com/gofiber/fiber/v2/middleware/basicauth"
	_ "github.com/mattn/go-sqlite3"
)

func main() {

	app := fiber.New()

	initDB()

	// Basic認証ミドルウェア設定
	app.Use(basicauth.New(basicauth.Config{
		Users: map[string]string{
			"arbitraryusername": "arbitrarypassword", // ユーザー名: パスワード
		},
		Realm: "Protected Area", // 認証ダイアログの表示名
	}))

	// 認証が通った場合のルート
	app.Get("/", Index)
	app.Get("/docs", getdocs) // documents.html

	app.Post("/post", post)
	app.Listen(":3000")
}

func Index(c *fiber.Ctx) error {
	return c.SendFile("./views/index.html")
}

func getdocs(c *fiber.Ctx) error {
	// テーブル取得のsqlコマンド(order指定がないので作成日時順になる)
	rows, err := db.Query("SELECT id, content FROM docs")
	if err != nil {
		log.Println("DB Query Error:", err)
		return c.Status(500).SendString("Internal Server Error")
	}
	// forループが終わったらqueryを戻す(テーブルのロックが解除される)
	defer rows.Close()

	var posts []map[string]string
	for rows.Next() {
		var id, content string
		if err := rows.Scan(&id, &content); err != nil {
			log.Println("DB Scan Error:", err)
			continue
		}
		posts = append(posts, map[string]string{
			"id":      id,
			"content": content,
		})
	}
	return c.JSON(posts)
}

func post(c *fiber.Ctx) error {
	// 受信するデータの構造体
	type RequestData struct {
		Content string `json:"content"`
	}
	var data RequestData
	err := c.BodyParser(&data)
	if err != nil {
		log.Println("json error")
		return c.Status(400).SendString("Invalid JSON")
	}

	// 受け取ったデータをsqlにinsert
	_, err = db.Exec("INSERT INTO docs ( content) VALUES ( ?)",
		data.Content)
	if err != nil {
		log.Println("DB Insert Error:", err)
		return c.Status(400).SendString("SQL Insert error")
	}

	return nil
}

var db *sql.DB

func initDB() {
	var err error
	db, err = sql.Open("sqlite3", "database.db")
	if err != nil {
		log.Fatal(err)
	}
	// テーブル作成
	createTableSQL := `
	CREATE TABLE IF NOT EXISTS docs (
		id INTEGER PRIMARY KEY AUTOINCREMENT,
		content TEXT
	);
	`
	_, err = db.Exec(createTableSQL)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("Database docs initialized")

}
index.html
<!DOCTYPE html>

<h1>contents</h1>
<label>posts:<textarea type="text" id="content">aiueo</textarea></label></br>
<label>got:<textarea type="text" id="got"></textarea></label>

<button type="button" onclick="createform()">create</button>

<table border="1">
    <thead>
        <tr>
            <th>ID</th>
            <th>Title</th>
        </tr>
    </thead>
    <tbody id="postsTable"></tbody>
</table>
<script>
    function createform() {
        // 入力値(json用)を取得
        let inputContent = document.getElementById("content").value;
        // 創成
        // 構造体に変換
        let data = {
            content: inputContent,
        };
        // リクエスト送信
        fetch(`/post`, {
            method: "POST",
            headers: { "Content-Type": "application/json" },
            body: JSON.stringify(data),
        });
    }
    async function loadPostsdefault() {
        const response = await fetch("/docs");
        if (!response.ok) {
            console.error("Failed to fetch posts");
            return;
        }
        const posts = await response.json();
        const table = document.getElementById("postsTable");
        table.innerHTML = ""; // クリア

        posts.forEach((post) => {
            let row = `<tr>
                    <td><button type="button" onclick="flushcontent(${post.id})">${post.id}</button></td>
                    <td>${post.content}</td>
                </tr>`;                    
            table.innerHTML += row;
        });
    }

    async function flushcontent(id){
        const response = await fetch("/docs");
        if (!response.ok) {
            console.error("Failed to fetch posts");
            return;
        }
        const posts = await response.json();
        const got = document.getElementById("got");
        got.value = posts[id-1].content;
        navigator.clipboard.writeText(posts[id - 1].content);
    }
    loadPostsdefault();
</script>

goの各ツール(go.exeから実行できるもの(go modなど))がどういうものなのかについてはあまり深く理解できていませんので割愛します。

ローカルでテスト

webアプリを作るのも初めてでして、色々調べながらやっていたところローカルでテストができることも初めて知りました。
go run main.goを実行すると、windows defenderの警告画面が出ます。プライベートにチェックを入れてやるとfiber実行中の旨表示されます。
ブラウザのアドレスバーにlocalhost:3000と入力するとwebアプリの動作確認ができます。

githubにアップロード

githubに作ったものをアップロードします。
githubのリポジトリを作ったときに下の方に書いてある通りのコマンドを実行します。

git init
git add main.go go.mod go.sum views/index.html 
git remote add origin (リポジトリのURL)
git push -u origin main

database.dbはテストでできたデータなのでアップロードしないよう注意してください。

renderに登録

ここからはrenderを使ってデプロイしていきます。
登録~githubと連携は割愛します。
新しいプロジェクトをつくる
image.png
githubリポジトリを選んでやると大体デフォルトで入力されている項目でよさそうなのでdeployボタンを押します。プランはfreeを選択しました。build commandとstart commandは理解できていません。

数分待つとビルドが完了してメールが届きます。
urlが出ていると思うので、そこにアクセスするとwebアプリが使えます。
image.png
なおfreeプランの制限で、このインスタンスは数分程度アクセスがないと初期化されるようです。

まとめ

  • renderの基本の使い方を理解した。
  • ネットワークやweb技術を理解する第一歩を踏み出せた。

わかっていないこと

  • goの各ツール(go.exe)

最後までお読みいただきありがとうございました。

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?