swift-server/swift-openapi-vapor

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.

Small question @0xTim or @MahdiBM, where can I find this documentation? Swift Package Index links me to here and I can't seem to find the added documentation.

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?)

Thanks @0xTim and @MahdiBM! I'll checkout the source in the meantime and wishing you both a nice weekend :)