HomeiOS DevelopmentNewbie's information to server-side Swift utilizing the Hummingbird framework

Newbie’s information to server-side Swift utilizing the Hummingbird framework



Swift on the Server in 2023


Three years in the past I began to deal with Vapor, the preferred web-framework written in Swift, which served me very properly through the years, however now it’s time to begin a brand new chapter in my life.


As I realized increasingly about how servers work I noticed that Vapor has it is personal professionals and cons. The neighborhood modified quite a bit throughout the previous 3 years, some core members left and new folks began to keep up the framework. I additionally had some struggles with the default template engine (Leaf) and just lately I began to show away from the summary database layer (Fluent) too. One other ache level for me is the rising variety of dependencies, I barely use websockets & multipart-kit, however Vapor has these dependencies by default and you may’t eliminate them. 😢


Vapor has some very nice issues to supply, and for most people it is nonetheless going to be a fantastic selection for constructing backends for frontends (BFFs). For me, Vapor reached its limits and I wished to make use of one thing that feels a bit lighter. Somethings that’s modular, one thing that may be simply prolonged and matches my precise wants with out extra (unused) package deal dependencies.


This shiny new factor is named Hummingbird and it appears very promising. It was created by Adam Fowler who’s a member of the SSWG and likewise the primary writer of the Soto library (AWS Swift).


Hummingbird has a complete documentation accessible on-line and a pleasant instance repository containing varied demo apps written utilizing the Hummingbird Swift server framework. I consider that the most effective a part of the the framework is modularity & extensibility. By the way in which, Hummingbird works with out Basis, however it has extensions for Basis objects, this can be a big plus for me, however possibly that is simply my private desire these days. Hummingbird will be prolonged simply, you’ll find some very helpful extensions beneath the Hummingbird challenge web page, lengthy story brief it really works with Fluent and it is comparatively straightforward to get together with it when you have some Vapor information… 🤔



Getting began with Hummingbird


To begin with, there isn’t any toolbox or command line utility to assist the kickoff course of, however you’ll be able to all the time obtain the examples repository and use one of many initiatives as a place to begin. Alternatively you’ll be able to set all the pieces up by hand, that is what we’ll do now. 🔨

With a view to construct a brand new utility utilizing the Hummingbird framework it’s best to create a brand new listing and initialize a brand new Swift package deal utilizing the next instructions:


$ mkdir server && cd $_
$ swift package deal init --type executable
¢ open Bundle.swift


It will create a brand new Swift package deal and open the Bundle.swift file in Xcode. You need to use your personal editor in the event you don’t love Xcode, however both method you may have so as to add Hummingbird to your package deal manifest file as a dependency. We’ll setup an App goal for the appliance itself, and a Server goal for the primary executable, which is able to use the appliance and configure it as wanted.



import PackageDescription

let package deal = Bundle(
    title: "server",
    platforms: [
        .macOS(.v10_15),
    ],
    dependencies: [
        .package(
            url: "https://github.com/hummingbird-project/hummingbird",
            from: "1.0.0"
        ),
        .package(
            url: "https://github.com/apple/swift-argument-parser",
            from: "1.0.0"
        ),
    ],
    targets: [
        .executableTarget(
            name: "Server",
            dependencies: [
                .product(
                    name: "ArgumentParser",
                    package: "swift-argument-parser"
                ),
                .target(name: "App"),
            ]
        ),
        .goal(
            title: "App",
            dependencies: [
                .product(
                    name: "Hummingbird",
                    package: "hummingbird"
                ),
                .product(
                    name: "HummingbirdFoundation",
                    package: "hummingbird"
                ),
            ],
            swiftSettings: [
                .unsafeFlags(
                    ["-cross-module-optimization"],
                    .when(configuration: .launch)
                ),
            ]
        ),
        .testTarget(
            title: "AppTests",
            dependencies: [
                .product(
                    name: "HummingbirdXCT",
                    package: "hummingbird"
                ),
                .target(name: "App"),
            ]
        ),
    ]
)


Please create the mandatory file and listing construction, as listed under, earlier than you proceed to the following steps. It is vitally essential to call issues as they seem, in any other case SPM will not work and the challenge will not compile. Anyway, the challenge construction is kind-of Vapor-like as you’ll be able to see. 💧


.
├── Bundle.resolved
├── Bundle.swift
├── README.md
├── Sources
│ ├── App
│ │ └── HBApplication+Configure.swift
│ └── Server
│     └── primary.swift
└── Exams
    └── AppTests
        └── AppTests.swift


The subsequent step is to create the primary entry level for the appliance. For this goal Hummingbird makes use of the Swift Argument Parser library. Place the next contents into the primary.swift file:

import ArgumentParser
import Hummingbird
import App

struct HummingbirdCommand: ParsableCommand {

    @Possibility(title: .shortAndLong)
    var hostname: String = "127.0.0.1"

    @Possibility(title: .shortAndLong)
    var port: Int = 8080

    func run() throws {
        let app = HBApplication(
            configuration: .init(
                handle: .hostname(hostname, port: port),
                serverName: "Hummingbird"
            )
        )
        strive app.configure()
        strive app.begin()
        app.wait()
    }
}

HummingbirdCommand.primary()


The HummingbirdCommand has two choices, you’ll be able to setup a customized hostname and port by offering these values as command line choices (I am going to present it afterward), the appliance itself will setup the handle utilizing the enter after which it will begin listening on the required port.


The configure technique comes from the App goal, that is the place you’ll be able to customise your server occasion, register route handlers and stuff like that, similar to you’d do that in Vapor. The primary distinction is that Hummingbird makes use of the HB namespace, which is fairly useful, and the configure technique is written as an extension. Let’s write it and register a fundamental route handler. 🧩


import Hummingbird
import HummingbirdFoundation

public extension HBApplication {

    func configure() throws {

        router.get("https://theswiftdev.com/") { _ in
            "Whats up, world!"
        }
    }
}


That is it. Now it’s best to have the ability to run your server, you’ll be able to press the Play button in Xcode that’ll begin your utility or enter one of many following instructions into the Terminal utility:



swift run Server


swift run Server --port 3000
swift run Server --hostname 0.0.0.0 --port 3000


swift run Server -p 3000
swift run Server -h 0.0.0.0 -p 3000


LOG_LEVEL=discover swift run Server -p 3000


swift construct -c launch


cp .construct/launch/Server ./Server


LOG_LEVEL=discover ./Server -p 3000


You may set these values in Xcode too, simply click on on the server scheme and choose the Edit Scheme… menu merchandise. Just be sure you’re on the Run goal, displaying the Arguments tag. Merely provde the Arguments Handed On Launch choices to set a customized hostname or port and you may set the log degree by including a brand new merchandise into the Atmosphere Variables part.


If you would like to unit take a look at your utility, I’ve received a excellent news for you. Hummingbird additionally comes with a pleasant utility instrument known as HummingbirdXCT, which you’ll simply setup & use if you would like to run some exams towards your API. In our challenge, merely alter the AppTests.swift file.

import Hummingbird
import HummingbirdXCT
import XCTest
@testable import App

ultimate class AppTests: XCTestCase {
    
    func testHelloWorld() throws {
        let app = HBApplication(testing: .dwell)
        strive app.configure()

        strive app.XCTStart()
        defer { app.XCTStop() }

        strive app.XCTExecute(uri: "https://theswiftdev.com/", technique: .GET) { response in
            XCTAssertEqual(response.standing, .okay)

            let expectation = "Whats up, world!"
            let res = response.physique.map { String(buffer: $0) }
            XCTAssertEqual(res, expectation)
        }
    }
}


As an alternative of making the appliance from the primary entry level, we will arrange a brand new HBApplication occasion, import the App framework and name the configure technique on it. the XCT framework comes with a customized XCTStart and XCTStop technique, and you may execute HTTP requests utilizing the XCTExecute operate. The response is accessible in a completion block and it is doable to look at the standing code and extract the physique utilizing a handy String initializer.


As you’ll be able to see Hummingbird is sort of much like Vapor, however it’s light-weight and you may nonetheless add these further issues to your server when it’s wanted. Hummingbird appears like the following iteration of Vapor. I actually do not know if Vapor 5, goes to repair the problems I am presently having with the framework or not, however I do not actually care, as a result of that launch will not occur anytime quickly.


Anyhow, I will use Hummingbird to construct some wonderful stuff (hopefully in public too) so in case you are simply comply with me on Twitter or Mastodon to ensure you get all the newest information.




RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments