Home iOS & Swift Books Server-Side Swift with Vapor

Fluent & Persisting Models Written by Tim Condon

In Chapter 2, “Hello, Vapor!”, you learned the basics of creating a Vapor app, including how to create routes. This chapter explains how to use Fluent to save data in Vapor applications. You’ll need to have Docker installed and running. Visit https://www.docker.com/get-docker and follow the instructions to install it.


Fluent is Vapor’s ORM or object relational mapping tool. It’s an abstraction layer between the Vapor application and the database, and it’s designed to make working with databases easier. Using an ORM such as Fluent has a number of benefits.

The biggest benefit is you don’t have to use the database directly! When you interact directly with a database, you write database queries as strings. These aren’t type-safe and can be painful to use from Swift.

Fluent benefits you by allowing you to use any of a number of database engines, even in the same app. Finally, you don’t need to know how to write queries since you can interact with your models in a “Swifty” way.

Models are the Swift representation of your data and are used throughout Fluent. Models are the objects, such as user profiles, you save and access in your database. Fluent returns and uses type-safe models when interacting with the database, giving you compile-time safety.


Over the next several chapters, you’ll build a complex “Today I Learned” application that can save different acronyms and their meanings. Start by creating a new project, using the Vapor Toolbox. In Terminal, enter the following command:

cd ~/vapor
vapor new TILApp

cd TILApp
rm -rf Sources/App/Models/*
rm -rf Sources/App/Migrations/*
rm -rf Sources/App/Controllers/*
open Package.swift

try app.register(collection: TodoController())
import Vapor
import Fluent

// 1
final class Acronym: Model {
  // 2
  static let schema = "acronyms"
  // 3
  var id: UUID?
  // 4
  @Field(key: "short")
  var short: String
  @Field(key: "long")
  var long: String
  // 5
  init() {}
  // 6
  init(id: UUID? = nil, short: String, long: String) {
    self.id = id
    self.short = short
    self.long = long
import Fluent

// 1
struct CreateAcronym: Migration {
  // 2
  func prepare(on database: Database) -> EventLoopFuture<Void> {
    // 3
      // 4
      // 5
      .field("short", .string, .required)
      .field("long", .string, .required)
      // 6
  // 7
  func revert(on database: Database) -> EventLoopFuture<Void> {
// 1
// 2
app.logger.logLevel = .debug

// 3
try app.autoMigrate().wait()
docker run --name postgres -e POSTGRES_DB=vapor_database \
  -e POSTGRES_USER=vapor_username \
  -e POSTGRES_PASSWORD=vapor_password \
  -p 5432:5432 -d postgres
docker ps

Saving models

When your app’s user enters a new acronym, you need a way to save it.

extension Acronym: Content {}
  "short": "OMG",
  "long": "Oh My God"
// 1
app.post("api", "acronyms") { req -> EventLoopFuture<Acronym> in
  // 2
  let acronym = try req.content.decode(Acronym.self)
  // 3
  return acronym.save(on: req.db).map { 
    // 4

Where to go from here?

This chapter has introduced you to Fluent and how to create models in Vapor and save them in the database. The next chapters build on this application to create a full-featured TIL application.

Have a technical question? Want to report a bug? You can ask questions and report bugs to the book authors in our official book forum here.

Have feedback to share about the online reading experience? If you have feedback about the UI, UX, highlighting, or other features of our online readers, you can send them to the design team with the form below:

© 2020 Razeware LLC

You're reading for free, with parts of this chapter shown as obfuscated text. Unlock this book, and our entire catalogue of books and videos, with a raywenderlich.com Professional subscription.

Unlock Now

To highlight or take notes, you’ll need to own this book in a subscription or purchased by itself.