Objects with application-wide scope in Swift Vapor

Viewed 58

How can I create objects within a Vapor-Applicaton that are instantiated when the app starts and are acessible from within my controllers?

I would like to use Dictionary to store some of my models across multiple requests and assign them to a user via hidden fields.

Unfortunately SessionData only accepts Strings.

Many thanks in advance

Michael

1 Answers

The obvious way is to extend Application. I used the documentation for Repositories as inspiration. First, create a structure to hold your properties:

struct AppConfig {
    var emailStatus: EmailStatus

    static var environment: AppConfig {
        return .init(emailStatus: .unknown)
    }
}

Then extend:

extension Application {
    struct AppConfigKey: StorageKey {
        typealias Value = AppConfig
    }

    var config: AppConfig {
        get {
            storage[AppConfigKey.self] ?? .environment
        }
        set {
            storage[AppConfigKey.self] = newValue
        }
    }
}

Finally, initialise in configure.swift:

app.config.emailStatus = .unknown

I’ve used an enumeration as an example but it can be whatever you want.

Edit: Addressing OP's issues and concerns

  1. I put the above code in a separate source file, so you need:
import Vapor

To gain access to StorageKey, etc.

  1. Accessing the running application instance in a controller is easy, it's available from the request as in request.application.
Related