Most server applications will need to store some data in a database. For Vapor applications, this is done with Fluent, a Swift Object-Relational-Mapper for persisting objects to a database. Fluent supports SQLite, Postgres, and Mysql. In this episode we will learn how to set up Fluent with a SQLite database for development. We'll create our first model object, and discuss how Fluent supports migrations for evolving the database schema over time.
Episode Links Fluent SQLite Base - SQLite Editor twostraws/vapor-clean - A Vapor 3 template with no additional cruft. Creating a Bare Vapor Project We are going to start by creating a project that has nothing in it. This will help us understand how to set up a dependency like Fluent. $ vapor new blog --template=https://github.com/twostraws/vapor-clean.git Once that is created, start the initial build. $ vapor build Adding FluentSQLite with Swift Package Manager We're going to use SQLite as our database for this demo. Let's open up Package.swift and add our dependency: // swift-tools-version:4.0 import PackageDescription let package = Package( name: "blog", dependencies: [ .package(url: "https://github.com/vapor/vapor.git", from: "3.1.0"), .package(url: "https://github.com/vapor/fluent-sqlite.git", from: "3.0.0") ], targets: [ .target(name: "App", dependencies: ["Vapor", "FluentSQLite"]), .target(name: "Run", dependencies: ["App"]), .testTarget(name: "AppTests", dependencies: ["App"]), ] ) We can build again to fetch this new dependency and then generate an Xcode project: $ vapor build $ vapor xcode Configuring the Database We need to configure our application to use the database. Open up configure.swift. import Vapor import FluentSQLite public func configure( _ config: inout Config, _ env: inout Environment, _ services: inout Services ) throws { // Other setup ... try services.register(FluentSQLiteProvider()) let db = try SQLiteDatabase(storage: .file(path: "db.sqlite")) var dbConfig = DatabasesConfig() dbConfig.add(database: db, as: .sqlite) services.register(dbConfig) } This will create our database as a file, located in the built products directory. You can see this path output in the console when you run the application in case you want to inspect the database manually. Creating a Model All Fluent models must implement the Model protocol. This provides information to the system about what type of primary key the model has, what the name of the table is, and whether it supports automatic timestamps like createdAt and updatedAt. In most cases, you can use the Model sub-protocol defined by the provider. import Vapor import FluentSQLite final class Post : SQLiteModel { var id: Int? var title: String var body: String var author: String var publishedAt: Date? static let entity = "posts" init(title: String, body: String, author: String) { self.title = title self.body = body self.author = author } } Configuring Migrations To get our posts table to be created, we need to make our model adopt the Migration protocol: extension Post : Migration { } Then we need to configure migrations to run on application startup. In configure.swift, after the database has been configured: var migrations = MigrationConfig() migrations.add(model: Post.self, database: .sqlite) services.register(migrations) We'll get the first migration for free, but as we alter this table and add new fields, we'll have to create migrations to update our database as well.