I just want to have a controller action that is basically doing the same as accessing an image directly through the Public/
folder. The difference is that the route can be whatever you want and the returned image will be the one that is determined inside of the controller function. But how to create a proper response?
My approach looks like this:
import Vapor
final class ImageController {
func read(_ req: Request) throws -> Future<Data> {
let directory = DirectoryConfig.detect()
let promise = req.eventLoop.newPromise(Data.self)
req.eventLoop.execute {
do {
let data = try Data(contentsOf: URL(fileURLWithPath: directory.workDir)
.appendingPathComponent("Public", isDirectory: true)
.appendingPathComponent("image.png"))
promise.succeed(result: data)
} catch {
promise.fail(error: error)
}
}
return promise.futureResult
// try req.content.encode(data, as: .png)
}
}
But it seems to me I'm overcomplicating it, do I?
But how to create a proper response?
Directly create a Response
and set the MediaType
: request.makeResponse(data, as: MediaType.png)
Example:
struct ImageController: RouteCollection {
func boot(router: Router) throws {
let imageRoutes = router.grouped("images")
// GET /images/get-test-image
imageRoutes.get("get-test-image", use: getTestImage)
}
func getTestImage(_ request: Request) throws -> Response {
// add controller code here
// to determine which image is returned
let filePath = "/path/to/image18.png"
let fileUrl = URL(fileURLWithPath: filePath)
do {
let data = try Data(contentsOf: fileUrl)
// makeResponse(body: LosslessHTTPBodyRepresentable, as: MediaType)
let response: Response = request.makeResponse(data, as: MediaType.png)
return response
} catch {
let response: Response = request.makeResponse("image not available")
return response
}
}
}
Two additional approaches:
A route using Leaf to deploy the image:
route.get("/my/random/route") {
request -> Future<View> in
return try request.view().render("image", ["imgname":"image.png"])
}
With image.leaf containing:
<img src="#(imgname)">
A re-direct to the original location in Public
:
route.get("/my/random/route") {
request -> Response in
return request.redirect(to: "/image.png")
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With