コンテンツとJSONエンコーディング
リクエストとレスポンスのボディをデコード・エンコードします。
「コンテンツとJSONエンコーディング」はCoddyKit上の無料Swift Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはSwift Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Swift Academyコースには全4レッスンが含まれています。
Content プロトコル
HTTP 経由でやり取りする Vapor のモデルは Content に準拠します。Content は Swift の Codable を基盤としており、リクエストボディからのデコードと、レスポンスへの自動エンコードの機能を追加します。
import Vapor
struct Todo: Content {
var id: Int?
var title: String
var done: Bool
}レスポンスの JSON エンコード
ハンドラーから任意の Content 値を返すと、Vapor が JSON にエンコードし、正しい Content-Type ヘッダーも自動的に設定します。
app.get("todo") { req -> Todo in
Todo(id: 1, title: "Learn Vapor", done: false)
}リクエストボディのデコード
req.content.decode(_:) を使うと、受信したリクエストから型付きのペイロードを読み取れます。Vapor は Content-Type を確認し、それに応じて JSON(またはフォームデータ)を解析します。
app.post("todo") { req -> Todo in
let incoming = try req.content.decode(Todo.self)
return incoming
}Content としての配列
Content 型のコレクションは、自動的に JSON 配列へエンコードされます。[Todo] を返すと、クライアントは JSON のリストを受け取ります。
app.get("todos") { req -> [Todo] in
[Todo(id: 1, title: "A", done: false),
Todo(id: 2, title: "B", done: true)]
}カスタムコーディングキー
Content は Codable なので、CodingKeys を使って Swift のプロパティ名を異なる JSON キーに対応付けられます。snake_case の API で役立ちます。
struct User: Content {
var firstName: String
enum CodingKeys: String, CodingKey {
case firstName = "first_name"
}
}JSON Encoder の設定
ContentConfiguration を使うと、すべてのキーを snake_case に変換したり、日付を ISO-8601 形式にしたりするなど、グローバルなエンコード戦略を設定できます。
let encoder = JSONEncoder()
encoder.keyEncodingStrategy = .convertToSnakeCase
encoder.dateEncodingStrategy = .iso8601
ContentConfiguration.global.use(encoder: encoder, for: .json)デコードした Content の検証
Vapor の Validatable プロトコルを使うと、検証ルールを宣言できます。デコードする前に try Todo.validate(content: req) を呼び出すと、不正な入力を明確な 400 エラーで拒否できます。
extension Todo: Validatable {
static func validations(_ v: inout Validations) {
v.add("title", as: String.self, is: !.empty)
}
}ハンドラーでの検証
まず検証し、その後でデコードします。検証に失敗すると、Vapor が自動的にエラーを送出し、クライアントは詳細なエラーレスポンスを受け取ります。
app.post("todo") { req -> Todo in
try Todo.validate(content: req)
return try req.content.decode(Todo.self)
}リクエストとレスポンスの DTO を分離する
入力と出力に異なる型を使うことは、よい実践方法です。たとえば、リクエストには id を持たない CreateTodo を使い、レスポンスには完全な Todo を使います。これにより、API と内部モデルを分離できます。
struct CreateTodo: Content {
var title: String
}
struct TodoResponse: Content {
var id: Int
var title: String
}クエリ文字列のエンコード
同じ Content の仕組みを使って、req.query.decode(_:) でクエリ文字列を構造体にデコードできます。フィルターやページネーションのパラメーターに適しています。
struct Page: Content {
var page: Int?
var size: Int?
}
app.get("items") { req -> String in
let p = try req.query.decode(Page.self)
return "page=" + String(p.page ?? 1)
}Content 付きカスタムステータスの返却
ボディとステータスの両方を制御するには、Response を構築してその中にコンテンツをエンコードするか、タプルのような構造を返します。以下では、JSON ボディとともに 201 Created を設定しています。
app.post("todo") { req -> Response in
let todo = try req.content.decode(Todo.self)
let res = Response(status: .created)
try res.content.encode(todo)
return res
}クイックチェック:Content と JSON
エンコードに関する知識を確認しましょう。
まとめ:Content と JSON エンコード
Vapor でデータを通信する方法を学びました。
- モデルを
Content(Codableを基盤とします)に準拠させます。 - コンテンツを返して JSON にエンコードし、
req.content.decodeでボディを読み取ります。 CodingKeysとContentConfigurationを使ってキーや日付をカスタマイズします。Validatableで入力を検証し、リクエストとレスポンスに別々の DTO を使うことを検討します。
よくある質問
「コンテンツとJSONエンコーディング」レッスンは無料ですか?
はい。「コンテンツとJSONエンコーディング」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Swift Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Swift Academyコースには全4レッスンが含まれています。
「コンテンツとJSONエンコーディング」で何を学びますか?
リクエストとレスポンスのボディをデコード・エンコードします。 ブラウザで直接実行するハンズオンコードでSwift Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Swift Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのSwift Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。
「コンテンツとJSONエンコーディング」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このSwift Academyレッスンでコードを書いて実行できますか?
はい。すべてのSwift Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- ルーティングとリクエスト処理
- コンテンツとJSONエンコーディング
- Fluent ORMとモデル
- ミドルウェアと認証