Getting Started with Fluent¶
Fluent provides an easy, simple, and safe API for working with your persisted data. Each database table/collection is represented by a Model
that can be used to interact with the data. Fluent supports common operations like creating, reading, updating, and deleting models. It also supports more advanced operations like joining, relating, and soft deleting.
Note
Don't forget to add import FluentProvider
(or your other database provider) to the top of your Swift files.
Fluent ships with SQLite by default. You can use SQLite to quickly scaffold your application with the in-memory database it provides. This is enabled by default in Vapor's default template. To learn more about configuring your database, check out the available drivers.
Creating a Model¶
Models are the Swift representations of the data in your database. As such, they are central to most of Fluent's APIs.
Let's take a look at what a simple model looks like.
final class Pet: Model { var name: String var age: Int let storage = Storage() init(row: Row) throws { name = try row.get("name") age = try row.get("age") } init(name: String, age: Int) { self.name = name self.age = age } func makeRow() throws -> Row { var row = Row() try row.set("name", name) try row.set("age", age) return row } }
Here we are creating a simple class Pet
with a name and an age. We will add a simple init method for creating new pets.
Storage¶
The storage
property is there to allow Fluent to store extra information on your model--things like the model's database id.
Row¶
The Row
struct represents a database row. Your models should be able to parse from and serialize to database rows.
Parse¶
Here's the code for parsing the Pet from the database.
final class Pet: Model { ... init(row: Row) throws { name = try row.get("name") age = try row.get("age") } }
Serialize¶
Here's the code for serializing the Pet to the database.
final class Pet: Model { ... func makeRow() throws -> Row { var row = Row() try row.set("name", name) try row.set("age", age) return row } }
Preparing the Database¶
In order to use your model, you may need to prepare your database with an appropriate schema.
Preparation¶
You can do this by conforming your model to Preparation
.
extension Pet: Preparation { static func prepare(_ database: Database) throws { try database.create(self) { pets in pets.id() pets.string("name") pets.int("age") } } static func revert(_ database: Database) throws { try database.delete(self) } }
Here we are creating a simple table that will look like this:
id | name | age |
---|---|---|
<database id type> | string | int |
Add to Droplet¶
Now you can add your model to the config's preparations so the database is prepared when your application boots.
import Vapor import FluentProvider let config = try Config() config.preparations.append(Pet.self) let drop = try Droplet(config) ...
Using Models¶
Now that we have created our model and prepared the database, we can use it to save and fetch data from the database.
Save¶
To save a model, call .save()
. A new identifier for the model will automatically be created.
let dog = Pet(name: "Spud", age: 5) try dog.save() print(dog.id) // the newly saved pet's id
Find¶
You can fetch a model from the database using it's ID.
guard let dog = try Pet.find(42) else { throw Abort.notFound } print(dog.name) // the name of the dog with id 42
Filter¶
You can also search for models using filters.
let dogs = try Pet.makeQuery().filter("age", .greaterThan, 2).all() print(dogs) // all dogs older than 2
Drivers¶
Check out the database section for more information about different database drivers you can use with Fluent.