Hide chapters

Server-Side Swift with Vapor

1 min

Before You Begin

Section 0: 3 chapters
Show chapters Hide chapters

Section I: Creating a Simple Web API

Section 1: 13 chapters
Show chapters Hide chapters

5. Fluent & Persisting Models
Written by Tim Condon

Heads up... You're reading this book for free, with parts of this chapter shown beyond this point as scrambled text.

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 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) { = 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"api", "acronyms") { req -> EventLoopFuture<Acronym> in
  // 2
  let acronym = try req.content.decode(Acronym.self)
  // 3
  return 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.
© 2023 Kodeco Inc.

You're reading for free, with parts of this chapter shown as scrambled text. Unlock this book, and our entire catalogue of books and videos, with a Kodeco Personal Plan.

Unlock now