Fluent Query
Penjelasan
Setelah model dan migration siap, kamu berinteraksi dengan database lewat query builder Fluent, dimulai dari Model.query(on: req.db). Method .all() mengambil semua baris, .filter(\Model.$field == nilai) menambah kondisi WHERE, .first() mengambil satu hasil pertama (atau nil), dan .sort(\Model.$field) mengurutkan hasil. Semua operasi ini bersifat asynchronous dan mengembalikan EventLoopFuture (atau bisa dipakai dengan await di handler async). Untuk menyimpan data baru, buat instance model lalu panggil .save(on: req.db); untuk memperbarui data yang sudah ada, ambil dulu lewat query, ubah property-nya, lalu panggil .save(on:) lagi (Fluent otomatis tahu ini UPDATE karena id sudah terisi). Menghapus data memakai .delete(on: req.db).
Contoh Konsep
import Fluent
import Vapor
func routes(_ app: Application) throws {
app.get("catatan") { req async throws -> [Catatan] in
try await Catatan.query(on: req.db).all()
}
app.get("catatan", "cari") { req async throws -> [Catatan] in
let kataKunci = req.query[String.self, at: "judul"] ?? ""
return try await Catatan.query(on: req.db)
.filter(\.$judul == kataKunci)
.all()
}
app.post("catatan") { req async throws -> Catatan in
let catatan = try req.content.decode(Catatan.self)
try await catatan.save(on: req.db)
return catatan
}
}
Praktikum
Buat route app.delete("catatan", ":id") yang mencari Catatan berdasarkan id parameter (pakai Catatan.find(id, on: req.db)), lalu kalau ditemukan panggil .delete(on: req.db) dan kembalikan status .noContent, kalau tidak ditemukan throw Abort(.notFound).
Ketik/edit bebas di sini untuk latihan — kode ini tidak dijalankan.
Tips
Perhatikan sintaks key path Fluent memakai tanda dolar di depan nama property (\.$judul, bukan \.judul) untuk merujuk wrapper @Field itu sendiri, bukan nilai mentahnya — ini bagian dari sintaks Swift property wrapper projected value, sama seperti $state di SwiftUI tapi dalam konteks berbeda.