Solution for using services in a fluent lifecycle event

vapor
fluent

(David Monagle) #1

Hi all,

I'm interested to know if there is an official or accepted way to achieve the following:

I have a model that is persisted to a postrgresql database. I also have an indexing service based on elasticsearch. For example, I would like to use the didUpdate lifecycle event on the PostgreSQL model to pass the model through to the indexing service. didCreate looks like this:

public func didUpdate(on conn: PostgreSQLConnection) throws -> EventLoopFuture<Account>

Now the problem here is that I don't have access to a container, only a connection - and by extension - an EventLoop.

I think the naive way of solving this would be to make the application a global object, allowing me to request a service from it. What I am curious about is whether Vapor has some mechanism that I haven't come across that allows an elegant way of achieving this?


(Tanner) #2

That part is by design. We want to keep Fluent decoupled from Vapor's dependency injection pattern.

I'd recommend against this as it will likely cause threading issues and make testing your code more difficult.


I think something like "Fluent-event middleware" could be used to solve this problem. They would need to be configurable during boot / initialization time so that any dependencies, such as indexing services, could be injected without prior knowledge of a given DI library. Each middleware could be registered against the events of a single model type, or receive the model type as a generic parameter.

Such a feature would definitely require a pitch / proposal process to iron out, but it's something that has been asked for before and would make Fluent a lot more extensible.