Information is on the heart of your software and in some unspecified time in the future, the way you symbolize that knowledge goes to alter. On this server-side Swift tutorial, you’ll learn to migrate the info on your Vapor functions. You’ll use PostgreSQL operating on Docker to retailer your knowledge. You’ll learn to view your knowledge in a PostgreSQL consumer for macOS, the right way to add fields on your mannequin, take away fields, the right way to add constraints, and the right way to seed your database with values.
Obtain the starter venture on the prime or backside of this web page by clicking on the Obtain Supplies button. RoomFinder is a Vapor software to mannequin convention rooms on your new startup. Unzip the downloaded file after which from a Terminal, cd into the folder that was unzipped and enter the next instructions:
open Package deal.swift
The primary command takes you into the listing of the starter venture for the RoomFinder app. The second command opens the venture in Xcode, utilizing Xcode 11’s new SwiftPM integrations.
Operating PostgreSQL On Docker
This tutorial requires you to run PostgreSQL on Docker. Assuming you’ve got Docker put in and operating on macOS, in Terminal, enter the next command:
docker run –name postgres -e POSTGRES_DB=vapor
-e POSTGRES_USER=vapor -e POSTGRES_PASSWORD=password
-p 5432:5432 -d postgres
Runs a brand new container named postgres.
Pulls down the picture if it at the moment doesn’t exist in your machine.
Specifies the database title, username and password by means of atmosphere variables.
Maps the host port 5432, which is the default port for Postgres, to the container port 5432.
The steps to connect with Postgres by means of your Vapor software are already carried out within the starter venture in Sources/App/configure.swift.
Create a Room Mannequin
You’ll begin by making a mannequin class for the convention room knowledge you need to migrate.
In Xcode, create a brand new file throughout the Sources/App/Fashions folder, and name the brand new file Room.swift:
Change the contents of the brand new file to the next:
ultimate class Room: Codable
var id: UUID?
The mannequin class incorporates a single non-compulsory UUID property to carry a room’s distinctive identifier if it has been set. As soon as the Room has been saved, it’s ID is about. All Fluent fashions should conform to Codable. The category is marked ultimate to offer efficiency advantages by the compiler.
Subsequent, you’ll add two extensions to Room.swift that make the Room class conform to comfort protocols. First,
extension Room: PostgreSQLUUIDModel
The Fluent packages present Mannequin comfort protocols for every database supplier and inform Fluent which sort the ID might be. There’s additionally PostgreSQLModel and PostgreSQLStringModel protocols for fashions with IDs of sort Int or String.
Now add the second extension:
extension Room: Content material
The Content material protocol is added with the intention to use this mannequin in your router.
Postico is a good free PostgresQL consumer for macOS that you should use for this tutorial. There’s a paid model as properly that provides you extra superior options, however you’ll solely want the free options. You’ll be able to obtain it at https://eggerapps.at/postico/.
As soon as Postico is put in, you may hook up with PostgreSQL on Docker identical to you’d if PostgreSQL was operating in your native machine with out Docker because you mapped your native port of 5432 to the container’s port of 5432. Enter the credentials you used earlier when creating your container, as within the screenshot beneath:
Bear in mind your tremendous secret password was password.
Once you first join Postico to your database, it ought to be empty:
Create the Room Migration
In an effort to save your Room mannequin knowledge into the database, you have to create a desk for it. That is performed by means of a migration. Migrations let you make repeatable modifications to your database. Through the use of migrations, you permit one other crew member to comply with in your footsteps by operating the identical set of migrations. For those who begin altering the database schema outdoors of Fluent, different crew members might be misplaced with out those self same set of guide migrations you probably did. It’s greatest apply to let the Fluent framework deal with the migration for you.
Within the Room mannequin, add the next extension on the backside:
extension Room: Migration
Now that your Room mannequin conforms to Migration, you’re in a position to inform Fluent to create the desk when the app begins. In configure.swift within the Sources/App folder, discover the part labeled // Configure migrations. Add the next earlier than companies.register(migrations):
migrations.add(mannequin: Room.self, database: .psql)
Set the energetic scheme to Run with My Mac because the vacation spot. Construct and run. Within the console, it’s best to see that your migration was run. It’s best to see one thing just like the console output beneath:
Now that your first migration has been run, in Postico you may click on the refresh icon within the toolbar on the fitting. It’s best to now see two tables, Fluent and Room:
The Fluent desk is utilized by the Fluent framework to maintain monitor of the migrations. Double-click on it and it’s best to see one entry like the next:
Breaking down the columns, the entry has a singular id, which is of sort UUID, that’s used as the first key within the Fluent desk. The title column is the title of the migration. That is the title of the migration you added in configure.swift. The batch column is the group of migrations that have been run at a single time. If a number of migrations are carried out on the identical time, they may all have the identical batch quantity. This fashion, when Fluent reverts a single migration, Fluent will roll again the migrations a part of the identical batch. The createdAt and updatedAt columns are the timestamps the migration was created at or up to date at, respectively.
When a brand new migration is executed, a row might be entered within the Fluent desk. For those who run your app once more, you’ll not see the Making ready migration ‘Room’ within the console. You shouldn’t edit this desk manually: You’re solely viewing it in Postico with a purpose to see how Fluent works in your behalf.
Click on on the vapor database icon within the prime toolbar to return to the tables view. Double-click on the Room desk.
You’ll be able to see the Room desk is empty because you haven’t added any Rooms but. You’ve solely created the desk to carry the Rooms. The desk has a single id column that matches the ID you created in code.
Click on on the underside segmented management Construction merchandise to see the desk construction.
By wanting on the desk construction for the Room desk, the id column’s sort is uuid that matches the ID sort you created in code in your Room mannequin.
Replace the Room Migration
At your startup, you rapidly understand that engineers aren’t going to need to find convention rooms by a UUID and would a lot slightly have a reputation for the room. This sounds prefer it’s time to replace your Room mannequin!
In Xcode, create a brand new folder within the Sources/App listing referred to as Migrations. Inside this new folder, create a file referred to as 0001_AddRoomName.swift. It’s greatest to have some kind of strategy to protect the order your migrations have to be run in. Two choices are to make use of the date of your migration or simply to quantity them so as. Right here you’ve chosen the latter.
In 0001_AddRoomName.swift, replace the code to the next:
struct AddRoomName: Migration
Discover the title of the struct doesn’t embrace the 0001_ prefix. That’s simply used to maintain monitor of your migrations, however doesn’t have to be a part of the struct. Migrations are sometimes written as a struct when updating an current mannequin. Migrations require you to offer three issues:
Fluent must know the kind of database the migration can run on.
A perform put together(on:) used to alter the database. In your case, you’ll add the property title to the Room mannequin.
A perform revert(on:) that’s the reverse of put together(on:). That is how Fluent is aware of the right way to undo a migration. In your case, eradicating the title property would undo the including of the title property.
Add the next to AddRoomName:
typealias Database = PostgreSQLDatabase
static func put together(on connection: PostgreSQLConnection) -> Future
return Database.replace(Room.self, on: connection) builder in
static func revert(on connection: PostgreSQLConnection) -> Future
Within the code above, you:
Inform Fluent that the database sort is PostgreSQL.
Inform Fluent which mannequin to replace. Discover you utilize replace right here. For those who have been creating a brand new mannequin in a migration, you’d use create.
Use the SchemaBuilder object to alter your database schema. On this case, you might be including a subject title on your Room mannequin.
In revert(on:), you do the alternative of what you probably did in put together(on:) and delete the sphere title.
The title property doesn’t exist in your Room mannequin but. In Room.swift, add the next to the Room class:
var title: String
Now every thing ought to compile, however to ensure that this migration to be run, it’s good to add it to the set of migrations to run in configure.swift. Under the earlier migration you added and earlier than companies.register(migrations), add:
migrations.add(migration: AddRoomName.self, database: .psql)
Construct and run. Refresh the view in Postico and it’s best to see a brand new column title of sort textual content was added for the Room desk”
Seeding Your Database
You will have a set of convention rooms which are prepared for use, however they aren’t within the database but. On this migration, you’ll seed the database with knowledge. Create a brand new file within the Migrations listing referred to as 0002_AddRooms.swift that you simply’ll use so as to add the rooms.
In 0002_AddRooms.swift, begin by altering the contents to the next:
struct AddRooms: Migration
typealias Database = PostgreSQLDatabase
This creates the AddRooms migration utilizing PostgreSQL because the database.
You begin to consider what you need to title your convention rooms and resolve on utilizing Apple frameworks as their names. In AddRooms, add put together(on:):
static func put together(on connection: PostgreSQLConnection) -> Future
let room1 = Room(title: “Basis”)
let room2 = Room(title: “UIKit”)
let room3 = Room(title: “SwiftUI”)
_ = room1.save(on: connection).remodel(to: ())
_ = room2.save(on: connection).remodel(to: ())
return room3.save(on: connection).remodel(to: ())
This creates three Room fashions. You name save(on:) for every of the fashions with a purpose to save the Room to the database. Since you don’t care about the results of the Future that’s returned, you may name remodel(to: ()) on it.
Then add the next code that can be utilized to reverse the modifications:
static func revert(on connection: PostgreSQLConnection) -> Future
In revert(on:), you utilize Fluent’s question and filter strategies to seek out the Rooms with the names you created in put together(on:). As soon as you discover them, you name delete() to take away these Rooms. Since you might be ready right here for a number of futures to finish, you utilize flatten(on:).
In configure.swift, add this new migration after migrations.add(migration: AddRoomName.self, database: .psql) and earlier than companies.register(migrations):
migrations.add(migration: AddRooms.self, database: .psql)
Construct and run. For those who view the content material of your Room desk, it’s best to see one thing just like:
There ought to be three rows for the three Rooms you added in your migration.
Reverting Your Migration
Up to now, you’ve been including fields and knowledge to your Room desk by calling put together(on:) in your migrations. However how does revert(on:) work?
To revert the migrations, it’s good to add CommandConfig. On the backside of the perform in configure.swift, beneath companies.register(migrations), add the next:
var commandConfig = CommandConfig.default()
CommandConfig means that you can register instructions to your container.
This provides Fluent instructions to the CommandConfig. Presently these are the migration instructions revert and migrate.
Registers the commandConfig service.
In an effort to run the revert command to revert your final migration, it’s good to add the revert possibility as a command-line argument. Edit your Run Scheme from the scheme chooser, or press Command-Possibility-R. This could appear to be:
Then run your app. Since you might be passing the revert argument on launch, within the console, Fluent asks if you wish to revert the final again of migrations. Enter y and press Enter.
Now for those who have a look at your Room desk, you’ll see it’s empty:
And for those who examine your Fluent desk, you see that it eliminated the final migration:
That is how one can revert a single migration. If you wish to revert your entire migrations, you may cross revert –all.
Because you really need the room knowledge, take away the revert command-line argument and run the app once more. It’s best to as soon as once more now have three rooms in your Room desk (you could have to hit the refresh button in Postico to see them).
Distinctive Room Migration
As your startup begins to develop and also you get extra convention rooms, as a lot as iOS builders are enthusiastic about SwiftUI, you don’t need somebody to create one other convention room with the identical title. It’s time for an additional migration! This migration will add a singular key to the title property of the desk.
Create a brand new file referred to as 0003_UniqueRoomNames.swift within the Migrations listing and replace the code to the next:
struct UniqueRoomNames: Migration
This units up the struct on your distinctive room migration. Subsequent add the put together(on:) methodology:
static func put together(on conn: PostgreSQLConnection) -> EventLoopFuture
On this migration, you utilize Database.replace(_:on:) like earlier than to replace your Room mannequin. To make a property distinctive, you utilize the distinctive(on:) perform, passing within the KeyPath of the distinctive subject. On this case, it’s the title KeyPath.
The reverse of this migration is to delete the distinctive key. Add the next code after put together(on:):
static func revert(on conn: PostgreSQLConnection) -> EventLoopFuture
In an effort to run this migration, add it to the configure.swift file above companies.register(migrations):
migrations.add(migration: UniqueRoomNames.self, database: .psql)
Earlier than operating the app once more, there are already routes created so that you can create a room and get the entire present rooms. In Sources/App/Controllers/RoomController.swift, uncomment the next code:
// func rooms(_ req: Request) throws -> Future<[Room]>
// return Room.question(on: req).all()
// func create(_ req: Request) throws -> Future
// return strive req.content material.decode(Room.self).flatMap room in
// return room.save(on: req)
In Sources/App/routes.swift, uncomment the next code:
// let roomController = RoomController()
// router.get(“rooms”, use: roomController.rooms)
// router.submit(“rooms”, use: roomController.create)
Construct and run.
Be aware: This tutorial makes use of the RESTed app, accessible as a free obtain from the Mac App Retailer. For those who like, you could use one other REST consumer to check your APIs.
Within the RESTed app, arrange a request as follows:
Your request ought to look just like the next:
Ship the request in RESTed and it’s best to see a response physique with the rooms already within the database.
Now attempt to create a room that already exists. Arrange a request as follows:
Add a single parameter referred to as title. Use a reputation that already exists like SwiftUI.
Choose JSON-encoded because the request sort. This ensures that the info is shipped as JSON and that the Content material-Kind header is about to software/json.
After sending your request, it’s best to get an error like so:
The error reveals that your migration so as to add the distinctive key to the room title property was profitable.
Migrations with Default Values
Engineers at your startup are collaborating increasingly, however they at the moment don’t understand how folks can slot in a room. Time so as to add that by means of a migration!
First, replace your Room mannequin by including a dimension property:
var dimension: Int
The compiler will complain that dimension shouldn’t be initialized. One possibility is to make this dimension property non-compulsory, however you would need to unwrap the non-compulsory each time you wished to make use of it. As a substitute, you may modify the default initializer to absorb the dimensions property. Exchange the initializer with the next code:
init(title: String, dimension: Int)
That is OK for creating new rooms from this level on, however you beforehand created rooms with the previous Room(title:) initializer while you seeded your database. You don’t need to change the earlier migration. Migrating knowledge is delicate and could be error-prone. A greater answer is to create a comfort initializer. Add the next beneath your earlier initializer:
comfort init(title: String)
Now for those who construct, your code will compile, and also you didn’t modify a previous migration.
It’s time so as to add the struct on your migration. Create a brand new file for the AddSizeToRoom migration within the Migrations listing referred to as 0004_AddSizeToRoom.swift. Replace the code within the file to the brand new migration:
struct AddSizeToRoom: Migration
This migration creates a default worth on your dimension column with the worth 2. You can have chosen zero right here just like the default worth of your struct, however that the rooms you’ve got can match no less than two folks. For those who question your knowledge sooner or later and also you see a Room that has a dimension of zero, somebody forgot to set the dimensions of the room earlier than creating it.
Add the migration to configure.swift above companies.register(migrations):
migrations.add(migration: AddSizeToRoom.self, database: .psql)
Construct and run. In Postico, it’s best to now see all 5 migrations in your Fluent desk:
Your Room desk ought to now have a brand new column referred to as dimension with a worth of two in every row:
That finishes all of the migrations on your convention room app!
As cleanup, now you can cease the Postgres Docker container you began earlier utilizing the next instructions in Terminal:
docker cease postgres
docker rm postgres
If you want, you may as well delete the Postgres Docker picture that was downloaded:
docker picture rm postgres
The place to Go From Right here?
You’ll be able to obtain the finished venture for this tutorial utilizing the Obtain Supplies button on the prime or backside of this web page.
This tutorial offers an summary of various migrations you could come throughout as you construct your Vapor software and your knowledge mannequin modifications. For those who loved this tutorial, why not try our full-length e book on Vapor growth: Server-Facet Swift with Vapor?
For those who’re a newbie to internet growth, however have labored with Swift for a while, you’ll discover it’s straightforward to create strong, fully-featured internet apps and internet APIs with Vapor three.
Whether or not you’re trying to create a backend on your iOS app, or need to create fully-featured internet apps, Vapor is the right platform for you.
You will discover extra Vapor tutorials in addition to tutorials utilizing the Kitura framework on our Server-Facet Swift web page.
Questions or feedback on this tutorial? Go away them within the feedback beneath!