mirror of https://github.com/vapor/docs.git
add updated services docs
This commit is contained in:
parent
a28ee6c7cf
commit
a271bb9aa8
|
|
@ -1,6 +1,6 @@
|
|||
# Using Crypto
|
||||
|
||||
Crypto is a library containing common APIs related to cryptography and data generation. The [vapor/crypto](https://github.com/vapor/crypto) package contains two modules:
|
||||
Crypto ([vapor/crypto](https://github.com/vapor/crypto)) is a library containing common APIs related to cryptography and data generation. The package contains two modules:
|
||||
|
||||
- `Crypto`
|
||||
- `Random`
|
||||
|
|
|
|||
|
|
@ -0,0 +1,51 @@
|
|||
# Getting Started with Service
|
||||
|
||||
Service ([vapor/service](https://github.com/vapor/service)) is a dependency injection (inversion of control) framework. It allows you to register, configure, and create your application's dependencies in a maintainable way.
|
||||
|
||||
```swift
|
||||
/// register a service during boot
|
||||
services.register(PrintLogger.self, as: Logger.self)
|
||||
|
||||
/// you can then create that service later
|
||||
let logger = try someContainer.make(Logger.self)
|
||||
print(logger is PrintLogger) // true
|
||||
```
|
||||
|
||||
You can read more about [dependency injection](https://en.wikipedia.org/wiki/Dependency_injection) on Wikipedia. Also be sure to check out the [Getting Started → Services](../getting-started/services.md) guide.
|
||||
|
||||
## Vapor
|
||||
|
||||
This package is included with Vapor and exported by default. You will have access to all `Service` APIs when you import `Vapor`.
|
||||
|
||||
```swift
|
||||
import Vapor
|
||||
```
|
||||
|
||||
## Standalone
|
||||
|
||||
The Service package is lightweight, pure-Swift, and has very few dependencies. This means it can be used as a dependency injection framework for any Swift project—even one not using Vapor.
|
||||
|
||||
To include it in your package, add the following to your `Package.swift` file.
|
||||
|
||||
```swift
|
||||
// swift-tools-version:4.0
|
||||
import PackageDescription
|
||||
|
||||
let package = Package(
|
||||
name: "Project",
|
||||
dependencies: [
|
||||
...
|
||||
.package(url: "https://github.com/vapor/service.git", from: "1.0.0"),
|
||||
],
|
||||
targets: [
|
||||
.target(name: "Project", dependencies: ["Service", ... ])
|
||||
]
|
||||
)
|
||||
```
|
||||
|
||||
Use `import Service` to access the APIs.
|
||||
|
||||
!!! warning
|
||||
Some of this guide may contain Vapor-specific APIs, however most of it should be applicable to the Services package in general.
|
||||
Visit the [API Docs](https://api.vapor.codes/service/latest/Service/index.html) for Service-specific API info.
|
||||
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
# Using Providers
|
||||
|
||||
The [`Provider`](https://api.vapor.codes/service/latest/Service/Protocols/Provider.html) protocol make it easy to integrate external services into your application. All of Vapor's official packages, like [Fluent](../fluent/getting-started.md), use the provider system to expose their services.
|
||||
|
||||
Providers can:
|
||||
|
||||
- Register services to your [`Services`](https://api.vapor.codes/service/latest/Service/Structs/Services.html) struct.
|
||||
- Hook into your [`Container`](https://api.vapor.codes/service/latest/Service/Protocols/Container.html)'s lifecycle.
|
||||
|
||||
## Register
|
||||
|
||||
Once you have added a Service-exposing [SPM dependency](../getting-started/spm/#dependencies) to your project, adding the provider is easy.
|
||||
|
||||
```swift
|
||||
import Foo
|
||||
|
||||
try services.register(FooProvider())
|
||||
```
|
||||
|
||||
This is usually done in [`configure.swift`](../getting-started/structure/#configureswift).
|
||||
|
||||
!!! note
|
||||
You can search GitHub for the [`vapor-service`](https://github.com/topics/vapor-service) tag for a list of packages that expose services using this method.
|
||||
|
||||
|
||||
## Create
|
||||
|
||||
Creating a custom provider can be a great way to organize your code. You will also want to create a provider if you are working on a third-party package for Vapor.
|
||||
|
||||
Here is what a simple provider would look like for the `Logger` examples from the [Services](services.md) section.
|
||||
|
||||
```swift
|
||||
public final class LoggerProvider: Provider {
|
||||
/// See `Provider`.
|
||||
public func register(_ services: inout Services) throws {
|
||||
services.register(PrintLogger.self)
|
||||
services.register(FileLogger.self)
|
||||
}
|
||||
|
||||
/// See `Provider`.
|
||||
public func didBoot(_ container: Container) throws -> Future<Void> {
|
||||
let logger = try container.make(Logger.self)
|
||||
logger.log("Hello from LoggerProvider!")
|
||||
return .done(on: container)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Now when someone registers the `LoggerProvider` to their `Services` struct, it will automatically register the print and file loggers. When the container boots, the success message will be printed to verify the provider was added.
|
||||
|
||||
See the [`Provider`](https://api.vapor.codes/service/latest/Service/Protocols/Provider.html) protocol's API docs for more information.
|
||||
|
|
@ -0,0 +1,104 @@
|
|||
# Using Services
|
||||
|
||||
This guide will show you how to register, configure, and create your own service. In this example we will be assuming two different `Logger` implementations.
|
||||
|
||||
- `PrintLogger`: Prints logs.
|
||||
- `FileLogger`: Saves logs to a file. Already conforms to `ServiceType`.
|
||||
|
||||
## Register
|
||||
|
||||
Let's take a look at how we can register our `PrintLogger`. First you must conform your type to `Service`. The easiest way to do this is simply adding the conformance in an extension.
|
||||
|
||||
```swift
|
||||
extension PrintLogger: Service { }
|
||||
```
|
||||
|
||||
It's an empty protocol so there should be no missing requirements.
|
||||
|
||||
### Factory
|
||||
|
||||
Now the service can be registered to the [`Services`](https://api.vapor.codes/service/latest/Service/Structs/Services.html) struct. This is usually done in [`configure.swift`](../getting-started/structure/#configureswift).
|
||||
|
||||
```swift
|
||||
services.register(Logger.self) { container in
|
||||
return PrintLogger()
|
||||
}
|
||||
```
|
||||
|
||||
By registering the `PrintLogger` using a factory (closure) method, we allow the [`Container`](https://api.vapor.codes/service/latest/Service/Protocols/Container.html) to dynamically create the service once it is needed. Any [`SubContainer`](https://api.vapor.codes/service/latest/Service/Protocols/SubContainer.html)s created later can call this method again to create their own `PrintLogger`s.
|
||||
|
||||
|
||||
### Service Type
|
||||
|
||||
To make registering a service easier, you can conform it to [`ServiceType`](https://api.vapor.codes/service/latest/Service/Protocols/ServiceType.html).
|
||||
|
||||
```swift
|
||||
extension PrintLogger: ServiceType {
|
||||
/// See `ServiceType`.
|
||||
static var serviceSupports: [Any.Type] {
|
||||
return [Logger.self]
|
||||
}
|
||||
|
||||
/// See `ServiceType`.
|
||||
static func makeService(for worker: Container) throws -> PrintLogger {
|
||||
return PrintLogger()
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Services conforming to [`ServiceType`](https://api.vapor.codes/service/latest/Service/Protocols/ServiceType.html) can be registered using just the type name. This will automatically conform to `Service` as well.
|
||||
|
||||
```swift
|
||||
services.register(PrintLogger.self)
|
||||
```
|
||||
### Instance
|
||||
|
||||
You can also register pre-initialized instances to `Services`.
|
||||
|
||||
```swift
|
||||
services.register(PrintLogger(), as: Logger.self)
|
||||
```
|
||||
|
||||
!!! warning
|
||||
If using reference types (`class`) this method will share the _same_ object between all [`Container`](https://api.vapor.codes/service/latest/Service/Protocols/Container.html)s and [`SubContainer`](https://api.vapor.codes/service/latest/Service/Protocols/SubContainer.html)s.
|
||||
Be careful to protect against race conditions.
|
||||
|
||||
## Configure
|
||||
|
||||
If more than one service is registered for a given interface, we will need to choose which service is used.
|
||||
|
||||
```swift
|
||||
services.register(PrintLogger.self)
|
||||
services.register(FileLogger.self)
|
||||
```
|
||||
|
||||
Assuming the above services are registered, we can use service [`Config`](https://api.vapor.codes/service/latest/Service/Structs/Config.html) to pick which one we want.
|
||||
|
||||
```swift
|
||||
switch env {
|
||||
case .production: config.prefer(FileLogger.self, for: Logger.self)
|
||||
default: config.prefer(PrintLogger.self, for: Logger.self)
|
||||
}
|
||||
```
|
||||
|
||||
Here we are using the [`Environment`](https://api.vapor.codes/service/latest/Service/Structs/Environment.html) to dynamically prefer a service. This is usually done in [`configure.swift`](../getting-started/structure/#configureswift).
|
||||
|
||||
!!! note
|
||||
You can also dynamically _register_ services based on environment instead of using service config.
|
||||
However, service config is required for choosing services that come from the framework or a provider.
|
||||
|
||||
## Create
|
||||
|
||||
After you have registered your services, you can use a [`Container`](https://api.vapor.codes/service/latest/Service/Protocols/Container.html) to create them.
|
||||
|
||||
```swift
|
||||
let logger = try someContainer.make(Logger.self)
|
||||
logger.log("Hello, world!")
|
||||
|
||||
// PrintLogger or FileLogger depending on the container's environment
|
||||
print(type(of: logger))
|
||||
```
|
||||
|
||||
!!! tip
|
||||
Usually the framework will create any required containers for you. You can use [`BasicContainer`](https://api.vapor.codes/service/latest/Service/Classes/BasicContainer.html) if you want to create one for testing.
|
||||
|
||||
|
|
@ -19,11 +19,14 @@ pages:
|
|||
- 'Async': 'getting-started/async.md'
|
||||
- 'Services': 'getting-started/services.md'
|
||||
- 'Deployment': 'getting-started/cloud.md'
|
||||
- 'Routing':
|
||||
- 'Getting Started': 'routing/getting-started.md'
|
||||
- 'Parameters': 'routing/parameters.md'
|
||||
- 'Route': 'routing/route.md'
|
||||
- 'Router': 'routing/router.md'
|
||||
- 'Crypto':
|
||||
- 'Getting Started': 'crypto/getting-started.md'
|
||||
- 'Digests': 'crypto/digests.md'
|
||||
- 'Ciphers': 'crypto/ciphers.md'
|
||||
- 'Asymmetric': 'crypto/asymmetric.md'
|
||||
- 'Random': 'crypto/random.md'
|
||||
- 'Deploy':
|
||||
- 'Getting Started': 'deploy/getting-started.md'
|
||||
- 'Fluent':
|
||||
- 'Getting Started': 'fluent/getting-started.md'
|
||||
- 'Models': 'fluent/models.md'
|
||||
|
|
@ -35,40 +38,41 @@ pages:
|
|||
- 'Pivot': 'fluent/pivot.md'
|
||||
- 'Transaction': 'fluent/transaction.md'
|
||||
- 'Database': 'fluent/database.md'
|
||||
- 'PostgreSQL':
|
||||
- 'Getting Started': 'postgresql/getting-started.md'
|
||||
- 'Fluent PostgreSQL': 'postgresql/fluent.md'
|
||||
- 'PostgreSQL Core': 'postgresql/core.md'
|
||||
- 'MySQL':
|
||||
- 'Getting Started': 'mysql/getting-started.md'
|
||||
- 'Fluent MySQL': 'mysql/fluent.md'
|
||||
- 'MySQL Core': 'mysql/core.md'
|
||||
- 'SQLite':
|
||||
- 'Getting Started': 'sqlite/getting-started.md'
|
||||
- 'Fluent SQLite': 'sqlite/fluent.md'
|
||||
- 'SQLite Core': 'sqlite/core.md'
|
||||
- 'Leaf':
|
||||
- 'Getting Started': 'leaf/getting-started.md'
|
||||
- 'Basics': 'leaf/basics.md'
|
||||
- 'Custom tags': 'leaf/custom-tags.md'
|
||||
- 'MySQL':
|
||||
- 'Getting Started': 'mysql/getting-started.md'
|
||||
- 'Fluent MySQL': 'mysql/fluent.md'
|
||||
- 'MySQL Core': 'mysql/core.md'
|
||||
- 'PostgreSQL':
|
||||
- 'Getting Started': 'postgresql/getting-started.md'
|
||||
- 'Fluent PostgreSQL': 'postgresql/fluent.md'
|
||||
- 'PostgreSQL Core': 'postgresql/core.md'
|
||||
- 'Redis':
|
||||
- 'Getting Started': 'redis/getting-started.md'
|
||||
- 'Basics': 'redis/basics.md'
|
||||
- 'Custom commands': 'redis/custom-commands.md'
|
||||
- 'Publish and Subscribe': 'redis/pub-sub.md'
|
||||
- 'Pipeline': 'redis/pipeline.md'
|
||||
- 'WebSocket':
|
||||
- 'Getting Started': 'websocket/websocket.md'
|
||||
- 'Crypto':
|
||||
- 'Getting Started': 'crypto/getting-started.md'
|
||||
- 'Digests': 'crypto/digests.md'
|
||||
- 'Ciphers': 'crypto/ciphers.md'
|
||||
- 'Asymmetric': 'crypto/asymmetric.md'
|
||||
- 'Random': 'crypto/random.md'
|
||||
- 'Routing':
|
||||
- 'Getting Started': 'routing/getting-started.md'
|
||||
- 'Parameters': 'routing/parameters.md'
|
||||
- 'Route': 'routing/route.md'
|
||||
- 'Router': 'routing/router.md'
|
||||
- 'Service':
|
||||
- 'Getting Started': 'service/getting-started.md'
|
||||
- 'Services': 'service/services.md'
|
||||
- 'Provider': 'service/provider.md'
|
||||
- 'SQLite':
|
||||
- 'Getting Started': 'sqlite/getting-started.md'
|
||||
- 'Fluent SQLite': 'sqlite/fluent.md'
|
||||
- 'SQLite Core': 'sqlite/core.md'
|
||||
- 'Testing':
|
||||
- 'Getting Started': 'testing/getting-started.md'
|
||||
- 'Deploy':
|
||||
- 'Getting Started': 'deploy/getting-started.md'
|
||||
- 'WebSocket':
|
||||
- 'Getting Started': 'websocket/websocket.md'
|
||||
- 'Version (3.0-rc)':
|
||||
- '1.5': 'version/1_5.md'
|
||||
- '2.0': 'version/2_0.md'
|
||||
|
|
|
|||
Loading…
Reference in New Issue