この内容は古いバージョンです。最新バージョンを表示するには、戻るボタンを押してください。
バージョン:3
ページ更新者:T
更新日時:2026-06-11 07:07:02

タイトル: アプリケーションの作成
SEOタイトル: Julia Genie アプリケーション作成完全ガイド

この記事の要点
  • Genie.Generator.newapp("MyApp") で MVC ディレクトリ一式を生成
  • 生成物: app/ (MVC) / config/ / db/ / public/ / bin/
  • ルーティングは config/routes.jl に集約。コントローラは app/resources/ 配下
  • ORM は SearchLight。PostgreSQL / MySQL / SQLite サポート
  • ビューは .html.jl (Julia 埋込) または Stipple のリアクティブテンプレート
  • 本番ビルドは PackageCompiler.jl でシステムイメージを焼いて起動高速化

Genie アプリ生成の全体像

Genie はジェネレータコマンドで MVC 構成を一発でスキャフォールドできます。Rails の rails new、Laravel の laravel new と同じ位置づけです。

1. 新規アプリ生成

# Julia REPL を起動
julia

# Genie 読み込み
using Genie

# 新規アプリ作成 (MVC フル構成)
Genie.Generator.newapp("MyApp")

# 種類別ジェネレータ
Genie.Generator.newapp_webservice("MyAPI")   # API 専用 (View 無し)
Genie.Generator.newapp_mvc("MyWeb")          # MVC (DB 付き)
Genie.Generator.newapp_fullstack("MyFull")   # MVC + アセットパイプライン

実行すると次のような処理が走ります:

  • ディレクトリ作成
  • Project.toml / Manifest.toml 生成
  • 依存パッケージインストール
  • config/secrets.jl にランダムキー生成
  • REPL から自動で起動

2. 生成されるディレクトリ構造

MyApp/
├── bin/
│   ├── repl              # REPL 起動
│   ├── server            # 本番サーバ起動
│   └── runtask           # タスク実行
├── bootstrap.jl
├── config/
│   ├── env/
│   │   ├── dev.jl
│   │   ├── prod.jl
│   │   └── test.jl
│   ├── initializers/
│   │   └── searchlight.jl
│   ├── routes.jl         # ★ ルーティング定義
│   └── secrets.jl
├── app/
│   ├── resources/
│   │   └── users/
│   │       ├── UsersController.jl
│   │       ├── User.jl         # モデル
│   │       └── views/
│   │           └── index.jl.html
│   └── layouts/
│       └── app.jl.html
├── db/
│   ├── migrations/
│   ├── connection.yml
│   └── seeds/
├── public/
│   ├── favicon.ico
│   └── img/
├── test/
└── Project.toml

3. ルーティング (config/routes.jl)

using Genie.Router
using UsersController

# 基本ルート
route("/") do
    "Welcome to MyApp"
end

# パラメータ
route("/users/:id::Int") do
    UsersController.show()
end

# HTTP メソッド指定
route("/users", UsersController.index)
route("/users", UsersController.create, method = POST)
route("/users/:id::Int", UsersController.update, method = PUT)
route("/users/:id::Int", UsersController.destroy, method = DELETE)

# リソースルート (CRUD 全部)
Router.resources(:users, UsersController)
# → GET    /users          UsersController.index
# → POST   /users          UsersController.create
# → GET    /users/:id      UsersController.show
# → PUT    /users/:id      UsersController.update
# → DELETE /users/:id      UsersController.destroy

# 名前付きルート
route("/login", LoginController.show, named = :login)
linkto(:login)   # "/login"

4. コントローラ

# app/resources/users/UsersController.jl
module UsersController

using Genie.Renderer.Html
using Genie.Renderer.Json
using Genie.Requests
using SearchLight
using Users  # モデル

function index()
    users = SearchLight.all(User)
    html(:users, :index, users = users)
end

function show()
    user = SearchLight.findone(User, id = params(:id))
    isnothing(user) && return Genie.Router.error(404)
    html(:users, :show, user = user)
end

function create()
    data = jsonpayload()
    user = User(name = data["name"], email = data["email"])
    if SearchLight.save(user)
        json(Dict("id" => user.id, "status" => "ok"), status = 201)
    else
        json(Dict("errors" => "validation failed"), status = 422)
    end
end

end

5. モデル (SearchLight ORM)

# app/resources/users/User.jl
module Users

using SearchLight
import SearchLight.AbstractModel

Base.@kwdef mutable struct User <: AbstractModel
    id::SearchLight.DbId = SearchLight.DbId()
    name::String = ""
    email::String = ""
    created_at::String = ""
end

end

# config/initializers/searchlight.jl で接続
using SearchLight
SearchLight.Configuration.load() |> SearchLight.connect

# 利用例
users = SearchLight.find(User, SQLWhereExpression("name LIKE ?", "%alice%"))
user  = SearchLight.findone(User, id = 1)
user.name = "New Name"
SearchLight.save!(user)

6. データベース設定 (db/connection.yml)

env: ENV["GENIE_ENV"]

dev:
  adapter: PostgreSQL
  host: localhost
  port: 5432
  database: myapp_dev
  username: postgres
  password: postgres

test:
  adapter: SQLite
  database: db/test.sqlite

prod:
  adapter: PostgreSQL
  host: db.example.com
  database: myapp_prod
  username: ENV["DB_USER"]
  password: ENV["DB_PASS"]

7. マイグレーション

# REPL から
using SearchLight, SearchLight.Migrations

# マイグレーション作成
SearchLight.Migrations.new_table_migration(:users)

# db/migrations/xxxxxxxx_create_table_users.jl
module CreateTableUsers

import SearchLight.Migrations: create_table, column, primary_key,
       add_index, drop_table

function up()
    create_table(:users) do
        [
            primary_key()
            column(:name, :string, limit = 100)
            column(:email, :string, limit = 200, not_null = true)
            column(:created_at, :datetime)
        ]
    end
    add_index(:users, :email, unique = true)
end

function down()
    drop_table(:users)
end

end

# 実行
SearchLight.Migrations.last_up()      # 最新を up
SearchLight.Migrations.last_down()    # ロールバック
SearchLight.Migrations.status()       # 状態確認

8. ビュー (.jl.html)


Users

9. 本番ビルド (PackageCompiler)

Julia の弱点である「起動が遅い」を解消するため、システムイメージを事前生成します:

using PackageCompiler

# システムイメージ生成
create_sysimage(
    [:Genie, :SearchLight, :MyApp];
    sysimage_path = "MyApp.so",
    precompile_execution_file = "precompile.jl",
)

# 起動時に指定
# julia -J MyApp.so --project=. bin/server
# → 初回起動 30 秒 → 2 秒

10. CLI でアプリ操作 (bin/runtask)

# REPL 起動
bin/repl

# サーバ起動 (本番)
bin/server

# カスタムタスク
bin/runtask seed_users

# マイグレーション
bin/repl
julia> using SearchLight.Migrations; last_up()

FAQ

Q: newapp() でエラーになる
A: 既存ディレクトリと衝突している可能性。空のディレクトリで再実行。または Genie.Generator.newapp_mvc 等を指定。

Q: SearchLight でなく別の ORM を使いたい
A: 直接 LibPQ.jl (PG) や MySQL.jl を呼んでも OK。コントローラから自由に SQL 実行可能。

Q: フロントは React / Vue を別で建てたい
A: API 専用なら newapp_webservice。CORS 設定後、フロントと分離開発できます。

Q: ホットリロードが効かない
A: ReviseGenie より先に読み込み、include でなく includet を使う。