All Projects → allegro → swiftbox

allegro / swiftbox

Licence: Apache-2.0 license
SwiftBox is a package that helps building Swift/Vapor microservices.

Programming Languages

swift
15916 projects
Makefile
30231 projects

Projects that are alternatives of or similar to swiftbox

ZEGBot
Build your Telegram Bot with Swift! (works on macOS / Ubuntu)
Stars: ✭ 52 (+188.89%)
Mutual labels:  server-side-swift
Lumpik
[experimental] Lumpik is a job queue system for general purpose.
Stars: ✭ 21 (+16.67%)
Mutual labels:  server-side-swift
HomeKitty
A Vapor 3 website to easily browse HomeKit accessories.
Stars: ✭ 75 (+316.67%)
Mutual labels:  server-side-swift
Perfect-Crypto
Cryptographic Operations
Stars: ✭ 27 (+50%)
Mutual labels:  server-side-swift
async
⏱ Promises and reactive-streams in Swift built for high-performance and scalability.
Stars: ✭ 35 (+94.44%)
Mutual labels:  server-side-swift
Perfect-HTTP
Base HTTP Support for Perfect.
Stars: ✭ 29 (+61.11%)
Mutual labels:  server-side-swift
Kitura-NIO
A networking library for Kitura, based on SwiftNIO
Stars: ✭ 35 (+94.44%)
Mutual labels:  server-side-swift
Perfect-XML
XML support for Perfect.
Stars: ✭ 16 (-11.11%)
Mutual labels:  server-side-swift
StORM
StORM base library
Stars: ✭ 19 (+5.56%)
Mutual labels:  server-side-swift
readme
Welcome to Vapor development at Nodes 📖
Stars: ✭ 47 (+161.11%)
Mutual labels:  server-side-swift
fluent-mysql-driver
🖋🐬 Swift ORM (queries, models, relations, etc) built on MySQL.
Stars: ✭ 69 (+283.33%)
Mutual labels:  server-side-swift
fluent-postgres-driver
🐘 PostgreSQL driver for Fluent.
Stars: ✭ 120 (+566.67%)
Mutual labels:  server-side-swift
Perfect-Weather
Demonstrate using URL Routes & variables, Fetching of remote data from API's as JSON, reading and transforming to data more appropriately consumable by an API client.
Stars: ✭ 32 (+77.78%)
Mutual labels:  server-side-swift
paginator
Offset pagination for Vapor 🗂
Stars: ✭ 67 (+272.22%)
Mutual labels:  server-side-swift
Perfect-SMTP
SMTP Client for Perfect.
Stars: ✭ 19 (+5.56%)
Mutual labels:  server-side-swift
sqlite-kit
Non-blocking SQLite client library with SQL builder built on SwiftNIO
Stars: ✭ 51 (+183.33%)
Mutual labels:  server-side-swift
model
Swift Kubernetes API objects
Stars: ✭ 18 (+0%)
Mutual labels:  server-side-swift
Perfect-URLRouting
Perfect Example Module: URL Routing
Stars: ✭ 20 (+11.11%)
Mutual labels:  server-side-swift
Perfect-Ubuntu
Install Swift and Perfect dependencies into an Ubuntu 16.04 system.
Stars: ✭ 37 (+105.56%)
Mutual labels:  server-side-swift
GraphQLRouteCollection
A GraphQL based RouteCollection for Vapor
Stars: ✭ 18 (+0%)
Mutual labels:  server-side-swift

SwiftBox

SwiftBox is a SwiftNIO based package that helps building Swift/NIO-based microservices.

Build Status Swift 5.3 Linux MacOS

What's included?

Running microservices with Swift requires:

  • logging capabilities
  • accessing configuration (e.g from Vault store)
  • pushing metrics to the metric store.

Coming soon: Integration with https://github.com/apple/swift-log.

SwiftBox Configuration

SwiftBox Configuration allows to pass type-safe configuration such as command line, environment variables and external providers (e.g Vault) by declaring one simple struct. Configuration can be inherited from multiple sources simultaneously.

Feed the configuration with:

  • Command line arguments: ./yourapp --config:simple=test --config:nested.number=1 --config:array.0=string
  • Environment variables: SIMPLE=test NESTED_NUMBER=1 ARRAY_0=string ./yourapp
  • JSON
  • Dictionary

SwiftBox Configuration supports:

  • overriding (source that is declared later can override previous values)
  • inheritance
  • optionals
  • type-safety
  • nesting (structs and arrays)
  • environment variables prefixes (avoid conflicting with system variables)

Usage

1. Import

Import module:

import SwiftBoxConfig

2. Configuration structure

When you create your configuration, remember that it in order to be decoded properly, it must conform to the Configuration protocol.

struct Conf: Configuration {
    let simple: String
    let int: Int
    let double: Double
    let nested: NestedConf // nested configuration
    let array: [String?] // array of optionals
    let arraynested: [NestedConf] // nested array

    struct NestedConf: Configuration {
        let value: String? // optional
    }
}

3. Bootstrap

Configuration must be bootstrapped before use. To do so, you need to conform to the ConfigManager protocol in the first place:

extension Conf: ConfigManager {
    public static var configuration: Conf? = nil
}

Next, call bootstrap method on your ConfigManager and pass sources you want to use:

try Conf.bootstrap(from: [EnvSource()])

Remember that bootstrap must be called before using config and cannot be called more than once. Otherwise, fatalError will be thrown.

4. Usage

After completing all the previous steps you can finally use config in your application. You can access the configuration instance via global property:

Conf.global.simple
Conf.global.int
Conf.global.double
Conf.global.array[0] // Optional[String]
Conf.global.nested.value // Optional[String]
Conf.global.arraynested[0].value // Optional[String]

Sources

Configuration can be fed with multiple sources. Sources are passed into bootstrap function.

If you are using multiple sources, outputs are merged (structs are merged recursively, other values are overridden):

try Conf.bootstrap(from: [
    DictionarySource(dataSource: [
        "int": 1,
        "string": "some",
        "array": [1, 2],
        "nested": ["value1": 1]
    ]),
    DictionarySource(dataSource: [
        "string": "test",
        "array": [2, 3],
        "nested": ["value2": 2]
    ]),
])

// Output config:
[
    "int": 1,
    "string": "test",
    "array": [2, 3],
    "nested": [
        "value1": 1,
        "value2": 2
    ]
]

Dictionary source

Allows reading configuration from Dictionary, may be used to specify in-code defaults for configuration.

Example
try Conf.bootstrap(from: [
    DictionarySource(dataSource: [
        "int": 1,
        "string": "some",
        "array": [1, 2],
        "nested": ["value1": 1]
    ])
])

JSON source

Allows reading configuration from JSON data.

Example
try Conf.bootstrap(from: [
    JSONSource(dataSource: "{\"test\": \"sample\"}")
])

Environment source

Allows reading configuration data from environment.

Example
try Conf.bootstrap(from: [
    EnvSource(prefix: "SAMPLE")
])

Prefix can be set for EnvSource, so it reads only variables which key starts with a given value.

Sample Configuration
struct Conf: Configuration {
    let simple: String
    let int: Int
    let double: Double
    let nested: NestedConf
    let array: [String?]
    let arraynested: [NestedConf]

    struct NestedConf: Configuration {
        let value: String?
    }
}

Above example may be populated using following env variables:

SIMPLE="test"
INT="1"
DOUBLE="1.0"
NULL="null"
NESTED_VALUE="test"
ARRAY_0="test0"
ARRAY_1="test1"
ARRAY_2="null"
ARRAYNESTED_0_VALUE="test0"
ARRAYNESTED_1_VALUE="test1"
ARRAYNESTED_2_VALUE="null"

Value "null" is coerced to internal nil value

Command line source

Allows reading configuration data from environment.

Example
Conf.bootstrap(from: [
    CommandLineSource(prefix: "--config:my-prefix-")
])

If a prefix is set, only arguments which start with a given value will be read. Defaults to --config:

Sample Configuration
struct Conf: Configuration {
    let simple: String
    let int: Int
    let double: Double
    let null: String?
    let nested: NestedConf
    let array: [String?]
    let arraynested: [NestedConf]

    struct NestedConf: Configuration {
        let value: String?
    }
}

The example above may be populated using following command line arguments:

--config:simple=test
--config:int=1
--config:double=1.0
--config:null=null
--config:nested.value=test
--config:array.0=test0
--config:array.1=test1
--config:array.2=null
--config:arraynested.0.value=test0
--config:arraynested.1.value=test1
--config:arraynested.2.value=null

Value "null" is coerced to internal nil value

Custom sources

To create custom sources, you need to create a class that conforms to ConfigSource. DictionarySource is the simplest working source that can be used as an example:

public typealias Storage = [String: Any?]

public class DictionarySource: ConfigSource {
    let dataSource: Storage

    public init(dataSource: Storage) {
        self.dataSource = dataSource
    }

    public func getConfig() throws -> Storage {
        return self.dataSource
    }
}

SwiftBoxLogging

Logging system for Swift.

Usage

1. Import

import SwiftBoxLogging

2. Bootstrap

Logging should be bootstrapped before use (it defaults to PrintLogger). Bootstrap requires one parameter which is the logger factory.

Logger factory must return LogHandler from swift-log package.

Logging.bootstrap { label in ElasticsearchLogHandler(label: name) }

2. Usage

Create a logger instance:

fileprivate var logger = Logging.make(#file)

Log a message using one of the available protocol methods:

func trace(_ message: String)
func info(_ message: String)
func debug(_ message: String)
func notice(_ message: String)
func warning(_ message: String)
func error(_ message: String)
func critical(_ message: String)

Custom Loggers

To create custom loggers your class must conform to LoggerProtocol.

Vapor

You can use the same logging by overriding Vapor's default log handler:

import Logging

LoggingSystem.bootstrap { label in
    ElasticsearchLogHandler(label: label)
}

SwiftBoxMetrics

StatsD and Logger handlers for official swift-metrics API.

Supported metric types:

  • Counters
  • Timers
  • Gauges

Usage

1. Import

import Metrics
import SwiftBoxMetrics

2. Bootstrap

Metrics must be bootstraped with Handler, which conforms to MetricsHandler protocol:

// StatsD Handler initialization
MetricsSystem.bootstrap(
    try! StatsDMetricsHandler(
        baseMetricPath: AppConfig.global.statsd.basePath!,
        client: UDPStatsDClient(
            config: UDPConnectionConfig(
                host: AppConfig.global.statsd.host!,
                port: AppConfig.global.statsd.port!
            )
        )
    )
)

// Logger Handler initialization
MetricsSystem.bootstrap(LoggerMetricsHandler())

3. Usage

Usage details can be found in official swift-metrics GitHub repository.

Handlers

LoggerMetricsHandler

Default metrics handler which sends gathered metrics to its logger.

StatsDMetricsHandler

StatsD Metrics Handler is responsible for sending gathered logs to StatsD server. Supports TCP and UDP protocols. Metrics are sent in separate thread, so operation is non-blocking for application.

try StatsDMetricsHandler(
    baseMetricPath: AppConfig.global.statsd.basePath!,
    client: UDPStatsDClient(
        config: UDPConnectionConfig(
            host: AppConfig.global.statsd.host!,
            port: AppConfig.global.statsd.port!
        )
    )
)

baseMetricPath is a path that will be prepended to every metric sent via handler. client is a TCPStatsDClient or UDPStatsDClient instance.

Custom Handlers

To create custom handlers, conform to MetricsHandler class.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].