Meet Corvus, the first strongly declarative server-side framework.

Overview

Corvus

Documentation MIT License Continuous Integration Swift 5.2


Corvus is the first truly declarative server-side framework for Swift. It provides a declarative, composable syntax which makes it easy to get APIs up and running. It is based heavily on the existing work from Vapor.

Example

Below is an example of a full-featured API that manages Bank Accounts and Transactions belonging to certain users. It also showcases the ease of using authentication and setting authorization rules for specific routes.

let xpenseApi = Api("api") {
    User<CorvusUser>("users")
    
    Login<CorvusToken>("login")
    
    BearerAuthGroup<CorvusToken> {
        AccountsEndpoint()
        TransactionsEndpoint()
    }
}

Because Corvus is composable, it is easy to use a group of components as its own component:

final class AccountsEndpoint: Endpoint {
    let parameter = Parameter<Account>()
    
    var content: Endpoint {
        Group("accounts") {
            Create<Account>().auth(\.$user)
            ReadAll<Account>().auth(\.$user)
            
            Group(parameter.id) {
                ReadOne<Account>(parameter.id).auth(\.$user)
                Update<Account>(parameter.id).auth(\.$user)
                Delete<Account>(parameter.id).auth(\.$user)
            }
        }
    }
}

How to set up

After your Swift Project, in the Package.Swift file, you will need to add the dependencies for Corvus and a Fluent database driver of your choice. Below is an example with an SQLite driver:

// swift-tools-version:5.2
import PackageDescription

let package = Package(
    name: "XpenseServer",
    platforms: [
        .macOS(.v10_15)
    ],
    products: [
        .library(name: "XpenseServer", targets: ["XpenseServer"])
    ],
    dependencies: [
        .package(url: "https://github.com/Apodini/corvus.git", from: "0.0.14"),
        .package(url: "https://github.com/vapor/vapor.git", from: "4.0.0"),
        .package(url: "https://github.com/vapor/fluent-sqlite-driver.git", from: "4.0.0-rc")
    ],
    targets: [
        .target(name: "Run",
                dependencies: [
                    .target(name: "XpenseServer")
                ]),
        .target(name: "XpenseServer",
                dependencies: [
                    .product(name: "Corvus", package: "corvus"),
                    .product(name: "FluentSQLiteDriver", package: "fluent-sqlite-driver")
                ]),
        .testTarget(name: "XpenseServerTests",
                    dependencies: [
                        .target(name: "XpenseServer"),
                        .product(name: "XCTVapor", package: "vapor"),
                        .product(name: "FluentSQLiteDriver", package: "fluent-sqlite-driver")
                    ])
    ]
)

Additionally, under the application's Source folder (by default that is Sources/App), two setup functions need to be present:

configure.swift, in which you can configure middlewares, databases and migrations used in the application:

import Corvus
import Vapor
import FluentSQLiteDriver

public func configure(_ app: Application) throws {
    app.middleware.use(CorvusUser.authenticator())
    app.middleware.use(CorvusToken.authenticator())
    
    app.databases.use(.sqlite(.file("db.sqlite")), as: .sqlite)
    app.migrations.add(CreateAccount())
    app.migrations.add(CreateTransaction())
    app.migrations.add(CreateCorvusUser())
    app.migrations.add(CreateCorvusToken())

    try app.autoMigrate().wait()
}

And routes.swift, which registers the routes from the Corvus API:

import Corvus
import Vapor

public func routes(_ app: Application) throws {
    try app.register(collection: xpenseApi)
}

Finally the application's main.swift file (which is usually under the path Sources/Run) should look like this:

import App
import Vapor

var environment = try Environment.detect()
try LoggingSystem.bootstrap(from: &environment)
let app = Application(environment)
try configure(app)
try routes(app)
defer {
    app.shutdown()
}
try app.run()

How to use

In general, there are two types of building blocks for a Corvus API: Group components, which allow users to group more groups or concrete endpoints under a common route path, or components that provide concrete functionality, like Create or ReadAll. Check out the docs and the example project to learn more!

How to contribute

Review our contribution guidelines for contribution formalities.

Sources

The logo: Made by Freepik

Vapor

Fluent

Comments
  • [BUG] Cannot build on Linux because LinuxMain.swift is missing

    [BUG] Cannot build on Linux because LinuxMain.swift is missing

    Describe the bug swift build fails because there is no LinuxMain.swift in the Test directory.

    To Reproduce Run swift build on Linux

    Expected behavior Corvus should be built successfully

    Environment (enter your versions):

    • Swift Version: 5.2.2
    • Xcode Version: -
    • Corvus Version: Head
    bug 
    opened by jhoogstraat 8
  • Feature/input dtos

    Feature/input dtos

    Provide a way to define the layout of request bodies and how the data is processed.

    Description

    Adds two Modifiers (SaveDTOModifier and UpdateDTOModifier) which require the programmer to define a struct conforming to either SaveDTOor UpdateDTO. These types are then decoded from the request body and used to save or update a model to the database.

    Ideas

    • Use Validations if present
    • use OperationType .patch for updating, because of its 'partial updating' nature.

    Related Issue

    Fixes 50% of #3

    Types of changes

    • [ ] Bug fix (non-breaking change which fixes an issue)
    • [x] New feature (non-breaking change which adds functionality)
    • [ ] Breaking change (fix or feature that would cause existing functionality to change)

    Checklist:

    • [x] SwiftLint throws no warnings or errors.
    • [x] I have updated the documentation accordingly.
    • [x] I have added tests to cover my changes.
    • [x] All new and existing tests passed.
    enhancement 
    opened by jhoogstraat 6
  • [FEATURE] Allow authentication via JWTs

    [FEATURE] Allow authentication via JWTs

    Is your feature request related to a problem? Please describe. I'd like to authenticate a User via a JWT that contains a payload.

    Describe the solution you'd like Implement a JWTAuthGroup that authenticates a JWT and injects it into req.auth. A CorvusJWTAuthenticator can be used to seperate the authentication from the group type.

    enhancement 
    opened by jhoogstraat 4
  • [FEATURE] Implement Mediator types

    [FEATURE] Implement Mediator types

    Problem

    It may not be desirable to always use CorvusModel for decoding the body of certain requests, like create or update requests.

    Solution

    To have more control over what the user is able to provide in a request body 'mediator', or 'carrier' types can be used. These types are also refered to as 'Data Transfer Objects' or DTOs. These can be implemented as DTOModifiers and ResponseModifier.

    Alternative Solutions

    Altering Create and Update endpoint to support these operations. Altering CorvusModel to inherit this functionality.

    enhancement 
    opened by jhoogstraat 4
  • Adds GuardGroup

    Adds GuardGroup

    This PR implements GuardGroup in conjuction with Guard.

    Related Issue

    Fixes #39

    Types of changes

    • [ ] Bug fix (non-breaking change which fixes an issue)
    • [x] New feature (non-breaking change which adds functionality)
    • [ ] Breaking change (fix or feature that would cause existing functionality to change)

    Checklist:

    • [x] SwiftLint throws no warnings or errors.
    • [x] I have updated the documentation accordingly.
    • [ ] I have added tests to cover my changes.
    • [x] All new and existing tests passed.
    opened by jhoogstraat 3
  • [FEATURE] Allow passing related objects as id for creating objects

    [FEATURE] Allow passing related objects as id for creating objects

    Currently, json has to be written like this to create objects:

    {
      "name": "Account",
      "user": {
        "id": "26132E11-6D13-4983-9FAE-71B705439BD8"
      }
    }
    

    It would be nice to only have to do this:

    {
      "name": "Account",
      "user": "26132E11-6D13-4983-9FAE-71B705439BD8"
    }
    

    This should be possible with DTOs.

    enhancement 
    opened by bmikaili 2
  • Adds JWTAuthGroup

    Adds JWTAuthGroup

    Fixes #40

    Description

    Related Issue

    Types of changes

    • [ ] Bug fix (non-breaking change which fixes an issue)
    • [x] New feature (non-breaking change which adds functionality)
    • [ ] Breaking change (fix or feature that would cause existing functionality to change)

    Checklist:

    • [ ] SwiftLint throws no warnings or errors.
    • [ ] I have updated the documentation accordingly.
    • [ ] I have added tests to cover my changes.
    • [ ] All new and existing tests passed.
    opened by jhoogstraat 1
  • [FEATURE] GuardGroup to allow for basic authorization

    [FEATURE] GuardGroup to allow for basic authorization

    Is your feature request related to a problem? Please describe. A new Type GuardGroup could be used to allow for the authorization of requests. This would allow a simple Role system, where each role has different access levels.

    Describe the solution you'd like Implement a new Group called GuardGroup which takes an array of Guard instances. A Guard is responsible for evaluating if the user is authorized to access the endpoint.

    Describe alternatives you've considered All other group types could get a new parameter guards: Guard....

    enhancement 
    opened by jhoogstraat 1
  • [BUG] Auth Groups block incoming requests with valid auth

    [BUG] Auth Groups block incoming requests with valid auth

    Describe the bug I am getting User not authenticated with auth groups.

    To Reproduce Just

    BasicAuthGroup<User>("login") {
        Custom<String>(type: .get) { req in
            req.eventLoop.makeSucceededFuture("Test")
        }
    }
    

    Expected behavior User should be authenticated.

    Environment:

    • Swift Version: 5.2
    • Xcode Version: 11.4.1
    • Corvus Version: develop branch
    • Database driver Version: Fluent SQLite Driver

    Additional context Works, if order is inverted:

    let guardedRoutesBuilder = groupedRoutesBuilder.grouped([
        T.authenticator(),
        T.guardMiddleware()
    ])
    
    bug 
    opened by jhoogstraat 1
  • Provide a functional default implementation of register in Endpoints

    Provide a functional default implementation of register in Endpoints

    Provide a functional default implementation of register in Endpoints

    Description

    Provide a functional default implementation of register(to routes: RoutesBuilder) for an Endpoint to enable Corvus Users to write composable Endpoints without the need to write a register(to routes: RoutesBuilder) function

    Related Issue

    Closes #7

    How Has This Been Tested?

    Ran the test suite

    Types of changes

    • [x] New feature (non-breaking change which adds functionality)

    Checklist:

    • [x] My code follows the code style of this project.
    • [x] My change requires a change to the documentation.
    • [x] I have updated the documentation accordingly.
    • [x] I have read the CONTRIBUTING document.
    • [x] I have added tests to cover my changes.
    • [x] All new and existing tests passed.
    enhancement 
    opened by PSchmiedmayer 1
  • Feature/refactor tests

    Feature/refactor tests

    Refactors the tests by splitting into separate files and following best practices in the Example Project.

    Types of changes

    • [ ] Bug fix (non-breaking change which fixes an issue)
    • [ ] New feature (non-breaking change which adds functionality)
    • [x] Breaking change (fix or feature that would cause existing functionality to change)

    Checklist:

    • [x] SwiftLint throws no warnings or errors.
    • [x] I have updated the documentation accordingly.
    • [x] I have added tests to cover my changes.
    • [x] All new and existing tests passed.
    enhancement 
    opened by bmikaili 0
Releases(0.0.16)
  • 0.0.16(Jun 7, 2020)

  • 0.0.15(May 30, 2020)

  • 0.0.14(May 15, 2020)

    Changes

    • [FEATURE] User endpoint auto-hash and validate @bmikaili (#31)
    • Feature/api class @jhoogstraat (#32)
    • Conforms Array to CorvusResponse @jhoogstraat (#33)
    • [BUG] Auth Groups block incoming requests with valid auth @bmikaili (#30)

    ๐Ÿš€ Features

    • Feature/modifier rework @bmikaili (#35)
    • Added buildEither method and updated CRUDs @bmikaili (#36)

    ๐Ÿ› Bug Fixes

    • Feature/modifier rework @bmikaili (#35)
    Source code(tar.gz)
    Source code(zip)
  • 0.0.13(Apr 17, 2020)

  • 0.0.12(Apr 17, 2020)

  • 0.0.11(Apr 16, 2020)

  • 0.0.10(Apr 14, 2020)

    Changes

    ๐Ÿš€ Features

    • Feature/auth support @bmikaili (#20)

    ๐Ÿ› Bug Fixes

    • Add a RestEndpointModfier protocol @PSchmiedmayer (#18)
    Source code(tar.gz)
    Source code(zip)
  • 0.0.9(Apr 10, 2020)

    ๐Ÿš€ Features

    • Implemented soft delete and restore @jhoogstraat (#5)
    • Adds RestEndpoint to decouple Endpoint from http. @jhoogstraat (#6)
    • Provide a functional default implementation of register in Endpoints @PSchmiedmayer (#8)
    • Feature/user endpoint @bmikaili (#9)
    • Feature/response modifier @jhoogstraat (#10)

    Changes

    • Fixes Corvus for Vapor 4.0.0 @jhoogstraat (#2) @jhoogstraat (#16)
    Source code(tar.gz)
    Source code(zip)
๐Ÿ’ง A server-side Swift web framework.

Vapor is a web framework for Swift. It provides a beautifully expressive and easy to use foundation for your next website, API, or cloud project. Take

Vapor 22.4k Jan 2, 2023
Enable WebSocket in OPC DA/AE Server with JSON return, first time ever

WebSocket4OPC Enable WebSocket in OPC DA/AE Server with JSON return, first time ever DCOM was developed more than 2 decades ago, wich was the pillar o

null 13 Dec 14, 2022
Apple Push Notifications (APNs) Server-Side library.

Perfect-Notifications ็ฎ€ไฝ“ไธญๆ–‡ APNs remote Notifications for Perfect. This package adds push notification support to your server. Send notifications to iO

PerfectlySoft Inc. 113 Oct 28, 2022
๐Ÿ“ฑ ย A strongly-typed, caching GraphQL client for iOS, written in Swift.

Apollo iOS is a strongly-typed, caching GraphQL client, written in Swift. It allows you to execute queries and mutations against a GraphQL server, and

Apollo GraphQL 3.6k Jan 7, 2023
Lazily deserialize JSON into strongly typed Swift objects

LazyObject Lazily deserialize JSON into strongly typed Swift objects, with a few getter style options. Is your app using it? Let me know! Installation

rob phillips 11 Nov 16, 2022
๐Ÿ“ก RealHTTP is a lightweight yet powerful client-side HTTP library.

RealHTTP RealHTTP is a lightweight yet powerful client-side HTTP library. Our goal is make an easy to use and effortless http client for Swift. Featur

Immobiliare Labs 233 Jan 7, 2023
Client side for goyotashi

B_2121_client ใ‚ตใƒผใƒใ‚ตใ‚คใƒ‰ใฏใ“ใกใ‚‰ Required Dependency Cocoa Pods โ€” https://guides.cocoapods.org/using/getting-started.html Getting Started โš ๏ธ M1 Mac ใฎๅ ดๅˆใ€ใ€ŒFinde

JPHACKS 2 Oct 31, 2021
An iOS library to route API paths to objects on client side with request, mapping, routing and auth layers

WANetworkRouting Developed and Maintained by ipodishima Founder & CTO at Wasappli Inc. Sponsored by Wisembly A routing library to fetch objects from a

null 10 Nov 20, 2022
Write clean, concise and declarative network code relying on URLSession, with the power of RxSwift. Inspired by Retrofit.

ReactiveAPI Reactive API library allows you to write clean, concise and declarative network code, with the power of RxSwift and URLSession! iOS Demo A

Sky UK Ltd 79 Nov 19, 2022
Declarative and Reactive Networking for Swift.

Squid Squid is a declarative and reactive networking library for Swift. Developed for Swift 5, it aims to make use of the latest language features. Th

Oliver Borchert 69 Dec 18, 2022
๐Ÿคต๐Ÿฝโ€โ™€๏ธ Janet โ€” A thin HTTP networking layer built on URLSession for simple, declarative endpoint specification leveraging the power of async/await.

????โ€โ™€๏ธ Janet โ€” Just another networking kit โ€” A thin HTTP networking layer built on URLSession for simple, declarative endpoint specification leveragi

Niklas Holloh 3 Sep 6, 2022
Deal with query items, HTTP headers, request body and more in an easy, declarative way

Reusable system for complex URL requests with Swift. Deal with query items, HTTP headers, request body and more in an easy, declarative way. Check out our engineering blog to learn more!

Parable Health 19 Sep 5, 2022
A Swift web framework and HTTP server.

A Swift Web Framework and HTTP Server Summary Kitura is a web framework and web server that is created for web services written in Swift. For more inf

Kitura 7.6k Jan 6, 2023
Swift backend / server framework (Pure Swift, Supports Linux)

NetworkObjects NetworkObjects is a #PureSwift backend. This framework compiles for OS X, iOS and Linux and serves as the foundation for building power

Alsey Coleman Miller 258 Oct 6, 2022
libuv base Swift web HTTP server framework

Notice Trevi now open a Trevi Community. Yoseob/Trevi project split up into respective Trevi, lime, middlewares and sys packages at our community. If

leeyoseob 46 Jan 29, 2022
Lightweight, flexible HTTP server framework written in Swift

Hummingbird Lightweight, flexible server framework written in Swift. Hummingbird consists of three main components, the core HTTP server, a minimal we

Hummingbird 245 Dec 30, 2022
Tiny http server engine written in Swift programming language.

What is Swifter? Tiny http server engine written in Swift programming language. Branches * stable - lands on CocoaPods and others. Supports the latest

null 3.6k Dec 31, 2022
Lightweight library for web server applications in Swift on macOS and Linux powered by coroutines.

Why Zewo? โ€ข Support โ€ข Community โ€ข Contributing Zewo Zewo is a lightweight library for web applications in Swift. What sets Zewo apart? Zewo is not a w

Zewo 1.9k Dec 22, 2022
Swift Express is a simple, yet unopinionated web application server written in Swift

Documentation <h5 align="right"><a href="http://demo.swiftexpress.io/">Live ?? server running Demo <img src="https://cdn0.iconfinder.com/data/icons/

Crossroad Labs 850 Dec 2, 2022