Chapter 8: Helper Functions for PUT, POST, DELETE

First, GREAT book so far – really looking forward to the full version. And of course, one big question:

In Chapter 8, you show how to use a helper function for a CREATE route, and mention these exist for PUT, POST, and DELETE as well. Trying to implement this for my updatHandler, I find the method update(on:, originalID:).

Trying my hand at doing this for PUT, I create a handler method…

	func updateHandler(_ req: Request, acronym: Acronym) throws -> Future<Acronym> {
		guard let acronymID = try? req.parameter(Int.self) else { throw Abort(.badRequest) }
		return acronym.update(on: req, originalID: acronymID)
	}

…which builds successfully, but I’m stuck on how to add it to boot(…). Obviously, the key difference with these 3 methods vs POST is that we also need to get the incoming ID parameter in our route. I tried several variants of things like:

	acronymsRoutes.put(Acronym.self, Int.parameter, use: updateHandler)`
	acronymsRoutes.put(Acronym.self, Acronym.parameter, use: updateHandler)`
   // lots more failed tries

The book states that we can add any needed path components before the use: parameter, but as soon as I try to add one, like above, Xcode throws an error “Argument type… does not conform to… DynamicPathComponentRepresentable”.

My best guess is would be that I most likely need to conform Acronym to DynamicPathComponentRepresentable implement makeDynamicPathComponents() per https://docs.vapor.codes/3.0/routing/parameters/. But this doesn’t seem to square with the fact that we successfully use Acronym.self elsewhere.

Can you point me in the right direction here?

@brian_bee the register line should probably be acronymsRoutes.put(Acronym.self, at: Acronym.parameter, use: updateHandler)

Fantastic! Thanks Tim :slight_smile:

I ended up with a lightly modified version of your suggestion for the route registration:

	acronymsRoutes.put(Acronym.self, at: Int.parameter, use: updateHandler)`

And then found that update(on: originalID:) still barked even when I supplied the originalID (I likely am misunderstanding the intent of the method). Happily, simply assigning the id to the acronym and using the simpler update(on:) does the trick quite nicely:

	func updateHandler(_ req: Request, acronym: Acronym) throws -> Future<Acronym> {
		guard let acronymID = try? req.parameter(Int.self) else { throw Abort(.badRequest) }
		acronym.id = acronymID
		return acronym.update(on: req)
	}

Thanks again :smile: