0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Web Development Framework Swiftlets

Posted at

SwiftでWebアプリケーションを開発しよう

背景

Paul Hudson氏が2024年にSwiftベースでWeb開発が可能となるIgniteを発表しました。SwiftのDSL機能を利用して、SwiftのプログラムでHTMLを書く感覚のDSLで、Webサイトが構築できる画期的な内容でした。ところが、実際にIgniteでWeb開発しようとすると、一つ問題となる事があります。それは、Igniteが動的なWebサイト構築をサポートしていない点でした。これは、つまり動的なサイトが一般的な現在では、利用できないという致命的な問題でした。

私はこれをなんとか解決できないかと思案しました。とにかく、DSLでHTMLを生成するアイデアは秀逸です。これに、パラメータやクッキーなど動的にページを生成できる仕組みがあれば、この仕組みは利用できると思いました。

ここで、こんなアイデアを思いつきました。ひと昔前のWeb ServerにCGIという仕組みがありました。このような仕組みを応用して、index.htmlがindex.swiftで書く事ができ、URLのパラメーター等がindex.swiftでコンパイルされた実行可能コードに受け渡されれば、動的なサイトの構築が可能ではないかと。

さらに、Apacheのように、実際のホストディレクトリ内の.htmlに相当する実行可能コードを.swiftで書くことができれば、面倒なルーティングも単純なディレクトリパスで実現できるというものでした。

Swiftletsとは

Swiftletsは、Swiftで動的なWebアプリケーションを開発するための軽量フレームワークです。ファイルベースルーティングとSwiftUIライクな宣言的構文を特徴とし、各URLパスを独立した実行可能モジュール("swiftlet")として扱います。

主な特徴

  • ファイルベースルーティング: ファイル構造がそのままURLパスになる
  • SwiftUIスタイルAPI: @Query@Cookieなどのプロパティラッパーで簡単にデータアクセス
  • 宣言的HTML DSL: SwiftUIライクな構文でタイプセーフにHTMLを生成
  • ホットリロード: 開発中はファイルを保存するだけで自動的にコンパイル・リロード
  • クロスプラットフォーム: macOSとLinuxの両方に対応

アーキテクチャ

Swiftletsのアーキテクチャは、従来のWebフレームワークとは大きく異なります。

1. ファイルベースルーティングシステム

用語について: この記事では「ルート」という用語が混乱を避けるため、以下のように使い分けています:

  • URLパス (route): /about/api/usersなどのWebアクセスパス
  • ルートディレクトリ (root): ディレクトリ構造の最上位
  • ルーティング (routing): URLパスとファイルのマッピング処理

2. CGIライクな実行モデル

各Swiftファイルは独立した実行可能ファイルにコンパイルされます。リクエストが来ると:

仕組みの詳細

.swiftファイル

.swiftファイルは独立したSwiftプログラムです:

import Swiftlets

@main
struct HomePage: SwiftletMain {
    @Query("name") var userName: String?
    @Cookie("theme") var theme: String?
    
    var title = "Welcome to Swiftlets!"
    
    var body: some HTMLElement {
        Html {
            Head {
                Title(title)
                Meta(name: "viewport", content: "width=device-width, initial-scale=1.0")
            }
            Body {
                Container(maxWidth: .large) {
                    H1("Hello, \(userName ?? "World")!")
                    P("Your theme preference: \(theme ?? "default")")
                }
            }
        }
    }
}

.webbinファイル

.webbinファイルは、そのディレクトリにURLパスが存在することを示すマーカーファイルです。これらはbuild-siteスクリプトによって自動生成され、サーバーがURLパスを識別するために使用します。

例えば、src/api/users.swiftがある場合、web/api/users.webbinが生成されます。

.binファイル(実行可能ファイル)

.swiftファイルは、プラットフォーム固有の実行可能ファイルにコンパイルされます:

  • macOS: bin/macos/{x86_64|arm64}/
  • Linux: bin/linux/{x86_64|arm64}/

これらの実行ファイルは:

  • 標準入力からJSONエンコードされたリクエストを受け取る
  • HTMLを生成してレスポンスを返す
  • 各リクエストごとに新しいプロセスとして実行される(CGIモデル)

開発フロー

1. サイトの作成

# 新しいサイトディレクトリを作成
mkdir -p sites/my-site/src
cd sites/my-site

2. ページの作成

// src/index.swift
import Swiftlets

@main
struct IndexPage: SwiftletMain {
    var body: some HTMLElement {
        VStack(spacing: 20) {
            H1("My First Swiftlets App")
            P("Building dynamic web apps with Swift!")
        }
    }
}

3. ビルドと実行

# サイトをビルド
./build-site sites/my-site

# サーバーを起動
./run-site sites/my-site

# ブラウザで http://localhost:8080 にアクセス

SwiftUIスタイルAPI

Swiftletsの最新バージョンでは、SwiftUIにインスパイアされたAPIを採用しています:

プロパティラッパー

@Query("search") var searchTerm: String?      // URLパラメータ
@FormValue("email") var email: String?        // フォームデータ
@Cookie("session") var sessionId: String?     // クッキー
@JSONBody<User>() var userData: User?         // JSONボディ
@Environment(\.request) var request: Request  // リクエスト情報

レスポンスビルダー

var body: ResponseBuilder {
    ResponseWith {
        // HTML content
    }
    .status(200)
    .cookie("session", value: newSessionId)
    .header("X-Custom-Header", value: "value")
}

まとめ

Swiftletsは、Swiftの強力な型システムとDSL機能を活用して、動的なWebアプリケーションを構築するための新しいアプローチを提供します。ファイルベースルーティングとCGIライクな実行モデルにより、シンプルで理解しやすいアーキテクチャを実現しています。

SwiftUIの経験があれば、すぐに使い始めることができ、iOSアプリ開発で培ったスキルをWebアプリケーション開発に活かすことができます。

リンク

0
2
1

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
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?