Add documentation on how to use Fluent(Kit)
jbehrens94 opened this issue · 10 comments
Currently, I am working on a side project using this Vapor OpenAPI generated package. I am missing documentation on how to use Fluent with the generated code. I would like to use Fluent and I think this is going to be a big use case.
An example of my code:
import FluentKit
import Foundation
import OpenAPIRuntime
import Vapor
struct UserController: APIProtocol {
typealias CreationInput = Operations.createUser.Input
typealias CreationOutput = Operations.createUser.Output
private let db: any Database
init(db: any Database) {
self.db = db
}
/// Create a user
///
/// - Remark: HTTP `POST /users`.
/// - Remark: Generated from `#/paths//users/post(createUser)`.
func createUser(_ input: CreationInput) async throws -> CreationOutput {
guard case let CreationInput.Body.json(input) = input.body else { fatalError() }
let user = try User
.Signup(name: input.name, email: input.email, password: input.password)
.createUser()
try await user.save(on: db)
let newUser = Components.Schemas.User(
name: user.name,
createdAt: user.createdAt ?? .now,
updatedAt: user.updatedAt ?? .now
)
let jsonBody: CreationOutput.Created.Body = .json(newUser)
let body = CreationOutput.Created(body: jsonBody)
return .created(body)
}
}
Which results in a warning: Stored property 'db' of 'Sendable'-conforming struct 'UserController' has non-sendable type 'any Database'
. Therefore, I would like to request documentation on how I am supposed to build out my Vapor app with FluentKit.
What you're doing is fine.
Since a few weeks ago Vapor itself is fully Sendable, but the warnings you get are related to Fluent as you've noted, and Fluent's Sendable compatibility is still in the works.
Though you're still right that there should be more documentation on how to use swift-openapi-vapor with existing Vapor projects, and that's something we should work on.
I don't think this is correct though. The UserController
should store a reference to Databases
not Database
. Database
in associated with one EventLoop
. You are limiting your performance if you use this.
If you have a reference databases: Databases
in your controller in your request handler you can get your Database
using
let database = databases.database(on: databases.eventLoopGroup.any())
This should make full use of all of your EventLoops when performing database operations.
@adam-fowler is right. database
is not the only thing that should delegate to a certain eventLoop like that (e.g. client
too), which happens by Vapor when used from a Request
, but it's probably the most important one.
@MahdiBM i guess that is the point of the issue there is no documentation covering this.
@adam-fowler @MahdiBM Your example uses the EventLoop, does this also apply async/await projects?
Vapor and basically all other server-side libraries that support async-await still use EventLoops underneath. So yes, it does apply.
Err @MahdiBM do you know what happened to the generated tutorials?
@jbehrens94 You can see the source here https://github.com/swift-server/swift-openapi-vapor/tree/main/Sources/OpenAPIVapor/Documentation.docc/Tutorials
We'll work on getting them fixed (and the README link updated!)
@jbehrens94 @0xTim It's available here: https://swiftpackageindex.com/swift-server/swift-openapi-vapor/main/tutorials/swift-openapi-vapor/requestinjection
Since i was not able to get Xcode working locally to actually test the tutorial, it looks suboptimal and it's also kind of hidden, but the content of the tutorial is what it should be so i only need to fix the "cosmetic" aspects of it.
It kind of fell out of priority after i merged it. I'll get to it probably somewhere around the weekend, assuming i can actually find a way to build the docs locally to test properly (new Xcode betas?)