jkrusnik / Apodini

Apodini - A declarative, composable server-side Swift framework

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Apodini

codecov jazzy Build and Test

A declarative, composable framework to build web services using Swift.

Getting Started

Installation

Apodini uses the Swift Package Manager:

Add it as a project-dependency:

dependencies: [
    .package(url: "https://github.com/Apodini/Apodini.git", .branch("develop"))
]

Add the base package and all exporters you want to use to your target:

targets: [
    .target(
        name: "Your Target",
        dependencies: [
            .product(name: "Apodini", package: "Apodini"),
            .product(name: "ApodiniREST", package: "Apodini"),
            .product(name: "ApodiniOpenAPI", package: "Apodini")
        ])
]

Hello World

Getting started is really easy:

import Apodini
import ApodiniREST

struct Greeter: Handler {
    @Parameter var country: String?

    func handle() -> String {
        "Hello, \(country ?? "World")!"
    }
}

struct HelloWorld: WebService {
    var configuration: Configuration {
        ExporterConfiguration()
            .exporter(RESTInterfaceExporter.self)
    }

    var content: some Component {
        Greeter()
    }
}

try HelloWorld.main()

// http://localhost:8080/v1 -> Hello, World!
// http://localhost:8080/v1?country=Italy -> Hello, Italy!

Apodini knows enough about your service to automatically generate OpenAPI docs. Just add the respective exporter:

import ApodiniOpenAPI
...
struct HelloWorld: WebService {
    var configuration: Configuration {
        ExporterConfiguration()
            .exporter(RESTInterfaceExporter.self)
            .exporter(OpenAPIInterfaceExporter.self)
    }
    ...
}

// JSON definition: http://localhost:8080/openapi
// Swagger UI: http://localhost:8080/openapi-ui

With Bindings we can re-use Handlers in different contexts:

struct Greeter: Handler {
    @Binding var country: String?

    func handle() -> String {
        "Hello, \(country ?? "World")!"
    }
}

struct HelloWorld: WebService {
    var configuration: Configuration {
        ExporterConfiguration()
            .exporter(RESTInterfaceExporter.self)
            .exporter(OpenAPIInterfaceExporter.self)
    }

    var content: some Component {
        Greeter(country: nil)
            .description("Say 'Hello' to the World.")
        Group("country") {
            CountrySubsystem()
        }
    }
}

struct CountrySubsystem: Component {
    @PathParameter var country: String
    
    var content: some Component {
        Group($country) {
            Greeter(country: Binding<String?>($country))
                .description("Say 'Hello' to a country.")
        }
    }
}

// http://localhost:8080/v1 -> Hello, World!
// http://localhost:8080/v1/country/Italy -> Hello, Italy!

Documentation

The framework is in early alpha phase. You can inspect the current development manifestos describing the framework in the documentation folder

You can find a generated technical documentation for the different Swift types at https://apodini.github.io/Apodini

Contributing

Contributions to this project are welcome. Please make sure to read the contribution guidelines first.

License

This project is licensed under the MIT License. See License for more information.

About

Apodini - A declarative, composable server-side Swift framework

License:MIT License


Languages

Language:Swift 99.6%Language:C 0.1%Language:HTML 0.1%Language:Dockerfile 0.1%Language:Lua 0.0%Language:Shell 0.0%