Server Side Swift with Vapor - Part 9: Controllers | Ray Wenderlich

There are conveniences for a few others as well - save is another good one. So you can do

let acronym = try req.content.decode(Acronym.self)
return acronym.save(on: req)

Or you can use the helper above. There are some nicer helper methods for you, but yes if you dig deep into the source they do all of the weird Async stuff so you don’t have to!

Where in the code does it make it possible to recognize the acronym ID tacked onto the end of the URL?

http://localhost:8080/api/acronyms/1<–?

@geosymani the magic happens here https://github.com/vapor/fluent/blob/master/Sources/Fluent/Model/Model.swift#L244

1 Like

I just created a new vapor project and the example it gives is VERY different than what you give. Is what they show the “new” way with a new version, or are your examples just a different way of doing it?

@gargoyle what way did it show you? When you say it’s different, how do you mean?

Its model inherits from Model, Preparation, JSONConvertible, ResponseRepresentable, etc

The controllers use ResourceRepresentable as the base.
It also now needs to have Row related stuff, as Model requires RowInitializable.

@gargoyle ah that’s a Vapor 2 project! (Shows how much boilerplate you needed for Vapor 2 models!) When you create the project with vapor new you still need to pass the --branch=beta flag until Vapor 3 is fully released (end of the week probably)

Any chance you could show how to query other tables in the routes? For example, in my OrderController on the post method, before I can call save() I actually have to make a few updates to the order itself. So I want to query the Point object for example
and that’s where I run into the issue because it seems like I need to do something like let points = try Point.query(on: req).all().wait() which is of course blocking.

@gargoyle you just need to unwrap the future. Basically do

return try Post.query(on:req).al().flatMap(to: ReturnType.self) { points in
  // do what you would have done after the `wait()` command
}

@0xtim Thanks, Tim. I hope the book is going to have a massive chapter explaining futures. This feels like pointers from C. They’re not hard at all, but until it “clicks” that first time, they’re so confusing to learn.

The EA has a chapter on it, but it will be expanded in the next release. It’s tricky though, there isn’t actually much to it, but the learning curve is steep!

In the current Vapor template there is a TodoController configured as a final class with the routes bound to the router in the routes.swift file. Is this the recommended way to do it moving forward or is there a benefit to using a struct that extends RouteCollection? The boot function is neat but I prefer having all of the routes bound in a single file. I’m guessing it’s a matter of preference but looking for some guidance. Thanks for the great video series Tim.

@owenjd it is a matter of preference really. The TodoController is a bit out of sync because it’s waiting for the RESTful controller protocol to be implemented.

Having all routes defined in a single file is up to. I prefer having controllers responsible for registering their own routes as it’s easier to add them in/remove them as needed and it stops routes.swift becoming a massive file for big projects.

I am getting:
Cannot convert value of type ‘AcronymsController’ to expected argument type
'Route Responder ’

Can you help with this? Thanks!

@0xtim Can you please help with this when you get a chance? Thank you - much appreciated! :]

@wlmsng can you show some code? I think it should be RouteCollection not RouteResponder

When I type import Vapor at the top, I don’t see Vapor as an auto-suggestion. Yet when I build and run the Vapor application everything works as intended. What’s up with that?

@greenteacorgi it’s a number of things. Sometimes if you haven’t built the application yet it won’t know what modules it can import. The other thing is that SPM and Xcode don’t play nice together at the moment, so it doesn’t know what modules are available until build time