
This video is only available to subscribers. Start a subscription today to get access to this and 478 other videos.
Creating, Updating, and Deleting Records with Fluent
This episode is part of a series: Server-side Swift with Vapor.
1. Getting Started with Vapor 12 min |
2. Vapor Routing 14 min |
3. Leaf Templates 13 min |
4. Nesting Templates and Partials 8 min |
5. Vapor Demo: Tokenizr 21 min |
6. Setting up a Database with Fluent 19 min |
7. Creating, Updating, and Deleting Records with Fluent 19 min |
8. Vapor Futures 20 min |
9. Setting up Vapor with Postgresql 17 min |
10. UUID Primary Keys 13 min |
11. Timestamp Fields 4 min |
12. Refactoring to Protocols 12 min |
13. Parent Child Relationships and Foreign Keys 14 min |
14. Pivot Tables for Many to Many Relationships 14 min |
15. Vapor Controllers 15 min |
16. Decoding Request Parameters 9 min |
Episode Links
- Fluent - Getting Started
- Fluent Models - Documentation
- httpstatus.es - a handy reference to look up HTTP status codes
Create a route to save a record
In the routes file:
router.get("_demo") { req -> Future<String> in
let post = Post(title: "Hello Fluent", body: "This is how you set up a database using Vapor Fluent", author: "Ben")
post.publishedAt = Date()
return post.save(on: req).map { post in
return "Created post with ID: \(post.id!)"
}
}
Deleting a record
We'll first see the hard way of doing it (because that's a great way to learn the magic behind Vapor) and then we'll look at an easier way.
router.delete("posts", Int.parameter) { req -> Future<String> in
let postId = try req.parameters.next(Int.self)
return Post.find(postId, on: req).flatMap { maybePost in
guard let post = maybePost else {
throw Abort(.notFound)
}
return post.delete(on: req).map {
return "deleted post: \(post.id!)"
}
}
}
As it turns out, fetching a record and performing an action on it is a really common operation, so Fluent has a great feature for making this easier.
Automatically fetching records as route parameters
Let's open up our Post.swift
file and add this at the bottom:
extension Post : Parameter {}
We can then alter the route above like this:
router.delete("posts", Post.parameter) { req -> Future<String> in
guard let futurePost = try? req.parameters.next(Post.self) else {
throw Abort(.badRequest)
}
return futurePost.flatMap { post in
return post.delete(on: req).map {
return "deleted post: \(post.id!)"
}
}
}
This is a huge time saver and shows off the power of Vapor's integration with Fluent.
Updating Records
Let's finish up our example by creating a route that will publish a post. In this example I want to return the JSON of the post we are modifying.
Let's go back to Post.swift
and add this at the bottom:
extension Post : Content {}
This tells Vapor that our model can be serialized. This uses Codable to return JSON representations of our models.
Now we can tell our route to simply return a Post
(in the future).
// PUT /posts/1/publish
router.put("posts", Post.parameter, "publish") { req -> Future<Post> in
try req.parameters.next(Post.self).flatMap { post in
post.publishedAt = Date()
return post.save(on: req)
}
}
As you can see, once you get used to the Future
syntax, manipulating records is fairly straightforward.