Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

History

33 Commits

Repository files navigation

Web

Web Framework

Key features:

Package.swift

.package(url:"https://github.com/swiftstack/web.git",.branch("dev"))

Fast as hell

About 80k rps on single core (i7 4gen, docker) using Fiber.

(docker) wrk -t1 -c128 -d5 http://0.0.0.0:8080/plaintext
Running 5s test @ http://0.0.0.0:8080/plaintext
1 threads and 128 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 1.64ms 310.35us 3.70ms 83.52%
Req/Sec 78.43k 8.95k 93.04k 76.00%
390020 requests in 5.10s, 28.64MB read
Requests/sec: 76500.26
Transfer/sec: 5.62MB

2 levels of abstraction

HTTP.Application - Simple API with minimum overhead
MVC.Application - Convenience API: Controller, Context, DependencyInjector

Both API levels have built-in Request->Model, Model->Response coders.

Bootstrap.swift

import HTTP
import Web
structWikiApplication:Bootstrap{func configure(services:Services)throws{try services.register(
singleton:InMemoryWikiRepository.self,
as:WikiRepository.self)}func configure(application:MVC.Application)throws{try application.addController(WikiController.self)}func configure(application:HTTP.Application)throws{
application.addHelloWorldRoute()}}

WikiController.swift

import HTTP
import Web
publicfinalclassWikiController:Controller,InjectService{letrepository:WikiRepositorypublicinit(_ repository:WikiRepository){self.repository = repository
}publicstaticfunc setup(router:ControllerRouter<WikiController>)throws{
router.route(get:"/:lang/:word", to: getDescription)}structGetDescription:Decodable{letlang,work:String}structDescription:Encodable{lettitle,body:String}func getDescription(request:GetDescription)throws->Description{guardlet description = repository.search(request)else{throwHTTP.Error.notFound
}return description
}}

HelloWorld.swift

import HTTP
extensionApplication{func addHelloWorldRoute(){route(get:"/plaintext"){ request inreturnResponse(string:"Hello, World")}}}

Simple Asynchronous API

All the modules built on top of Async which allows us to code without callbacks.
The API is easy to use, easy to read and easy to update to async/await in the future.

main.swift

import Async
import Web
import Log
async{do{letapplication=tryWebHost(bootstrap:WikiApplication())try application.run(at:"0.0.0.0", on:8080)}catch{Log.critical(String(describing: error))}}
loop.run()

Built-in Dependency Injector

You can inject up to 6 services (out of the box).
The service can be either Context or :Injectable.

NOTE: the ininializer arguments must have no labels.

import Web
finalclassSimpleController:Controller,Inject2Services{letcontext:Contextletrepository:SomeRepositoryinit(_ context:Context, _ repository:SomeRepository){self.context = context
self.repository = repository
}}

singleton - shared instance per application
transient - new instance per request

letservices=Servises.shared
services.register(
singleton:MyImplementation.self,
as:SomeProtocol.self)
services.register(
transient:MyImplementation.self,
as:SomeProtocol.self)
services.register(singleton:SomeProtocol.self){returnMyImplementation()}
services.register(transient:SomeProtocol.self){returnMyImplementation()}

About

Advanced HTTP Server: Controllers, DI, etc..

Topics

Resources

Stars

4 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages