Chapters

Hide chapters

Server-Side Swift with Vapor

Third Edition · iOS 13 · Swift 5.2 - Vapor 4 Framework · Xcode 11.4

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

31. Advanced Fluent
Written by Tim Condon

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now

In the previous sections of this book, you learned how to use Fluent to perform queries against a database. You also learned how to perform CRUD operations on models. In this chapter, you’ll learn about some of Fluent’s more advanced features. You’ll see how to save models with enums and use Fluent’s soft delete and timestamp features. You’ll also learn how to use raw SQL and joins, as well as seeing how to “eager load” relationships.

Getting started

The starter project for this chapter is based on the TIL application from the end of chapter 21. You can either use your code from that project or use the starter project included in the book materials for this chapter. This project relies on a PostgreSQL database running locally.

Clearing the existing database

If you’ve followed along from the previous chapters, you need to delete the existing database. This chapter contains model changes which require either reverting your database or deleting it. In Terminal, type:

Creating a new database

Create a new database in Docker for the TIL application to use. In Terminal, type:

Soft delete

In Chapter 7, “CRUD Database Operations”, you learned how to delete models from the database. However, while you may want models to appear deleted to users, you might not want to actually delete them. You could also have legal or company requirements which enforce retention of data. Fluent provides soft delete functionality to allow you to do this. Open the TIL app in Xcode and go to User.swift. Look for:

Restoring Users

Even though the application now allows you to soft delete users, you may want to restore them at a future date. First, add the following below import Vapor at the top of UsersController.swift:

Force delete

Now that you can soft delete and restore users, you may want to add the ability to properly delete a user. You use force delete for this. Back in Xcode, still in UsersController.swift, create a new route to do this. Add the following below restoreHandler(_:):

Timestamps

Fluent has built-in functionality for timestamps for a model’s creation time and update time. In fact, you used one above to implement soft-delete functionality. If you configure these, Fluent automatically sets and updates the times. To enable this, open Acronym.swift in Xcode. Below var categories: [Category] add two new properties for the dates:

Enums

A common requirement for database columns is to restrict the values to a pre-defined set. Both FluentPostgreSQL and FluentMySQL support enums for this. To demonstrate this, you’ll add a type to the user to define basic user access levels. In Xcode, create a new file called UserType.swift in Sources/App/Models. Open the new file and add the following:

Lifecycle hooks

Fluent allows you to hook into various aspects of a model’s lifecycle using model middleware. These work in a similar way to other middleware and allow you to execute code before and after different events. For more information on middleware, see Chapter 29, “Middleware”. Fluent allows you to add middleware for the following events:

Eager loading and nested models

If you follow a strict REST API, you should retrieve a model’s children in a separate request. However, this isn’t alway ideal, and you may want the ability to send a single request to get all models with all their children. For example, in the TIL application, you may want a route that returns all categories with all their acronyms. You may even want to return all categories with all their acronyms with all their users. This is commonly referred to as the N+1 problem and Fluent makes this easy with eager loading. Open CategoriesController.swift and add the following at the bottom of the file:

Joins

Sometimes, you want to query other tables when retrieving information. For example, you might want to get the user who created the most recent acronym. You could do this with eager loading and Swift. You’d do this by getting all the users and eager load their acronyms. You can then sort the acronyms by their created date to get the most recent and return its user. However, this means loading all users and their acronyms into memory, even if you don’t want them, which is inefficient. Joins allow you to combine columns from one table with columns from another table by specifying the common values. For example, you can combine the acronyms table with the users table using the users’ IDs. You can then sort, or even filter, across the different tables.

Raw SQL

Whilst Fluent provides tools to allow you to build lots of different behaviors, there are some advanced features it doesn’t offer. Fluent doesn’t support querying different schemas or aggregate functions. In a complex application, you may find that there are scenarios where Fluent doesn’t provide the functionality you need. In these cases, you can use raw SQL queries to interact with the database directly. This allows you to perform any type of query the database supports.

Where to go from here?

In this chapter, you learned how to use some of the advanced features Fluent provides to perform complex queries. You also saw how to send raw SQL queries if Fluent can’t do what you need.

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.
© 2026 Kodeco Inc.

You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now