Live 🐧 server running Demo Live 🐧 server running Demo Live 🐧 server running Demo

Swift Express is a simple, yet unopinionated web application server written in Swift

Overview

Swift Express

Twitter Facebook LinkedIn Web site Slack

Documentation
	<h5 align="right"><a href="http://demo.swiftexpress.io/">Live 🐧 server running Demo  <img src="https://cdn0.iconfinder.com/data/icons/glyphpack/34/play-circle-32.png" height=16/></a></h5>
	
	<h5 align="right"><a href="http://swiftexpress.io/">Eating our own dog food  <img src="https://cdn0.iconfinder.com/data/icons/glyphpack/147/globe-full-32.png" height=16/></a></h5>
	<br/>
</p>

🐧 linux: ready Build Status SPM compatible Platform OS X | Linux Swift version ![GitHub license](https://img.shields.io/badge/license-LGPL v3-green.svg) GitHub release

UPDATE March 2017: Swift Express is back on track and is Swift 3.x compatible. From now on we will suport the latest stable swift builds only. There is no release of the newest version done yet, though you can enjoy it from the "master" branch. Stay tuned.
Version 0.3.x (current stable) notice: Current version works with Xcode 7.2, 7.3 and Linux DEV SNAPSHOT released on 03.01.2016. Upcoming version (0.4.x) will fully support Swift 3.0 and will maintain compatibility with Swift 2.2 (Xcode 7.3). Stay tuned by following us on social networks.

Being perfectionists, we took the best from what we think is the best: power of Play Framework and simplicity of Express.js

Express is an asynchronous, simple, powerful, yet unopinionated web application server written in Swift

Getting started

First make sure, please, you have followed the installation section steps.

Create a project:
swift-express init HelloExpress
cd HelloExpress
swift-express bootstrap
open HelloExpress.xcodeproj
Create new API:
app.get("/myecho") { request in
    .ok(request.query["message"]?.first)
}
Run from xCode or command line with:
swift-express build
swift-express run

Test it in the browser: http://localhost:9999/myecho?message=Hello

A complete Swift Express command line documentation can be found here: https://github.com/crossroadlabs/ExpressCommandLine

Installation

OS X OS X

First install the following components (if you have not yet):
  • XCode 7.2 or higher
  • Homebrew the latest available version
  • Command Line tools: run xcode-select --install in terminal
Run the following in terminal:
brew tap crossroadlabs/tap
brew install swift-express

Linux Linux

For instructions on how to get Express installed on Linux, please, refer to the installation section in the ducumentation.

Examples

Create a project as it is described in the getting started section. Now you can start playing with examples.

All the examples can be found in Demo project inside the main repo.

Hello Express:

app.get("/hello") { request in
    .ok(AnyContent(str: "<h1>Hello Express!!!</h1>", contentType: "text/html"))
}

Launch the app and follow the link: http://localhost:9999/hello?message=Hello

Synchronous vs Asynchronous

If you don't know what this is you might want to better skip it for now to the next section: URL params. To get more information see this first. We have our APIs based on Future pattern. Our implementation is based on BrightFutures, thanks @Thomvis!

Express can handle it both ways. All your syncronous code will be executed in a separate queue in a traditional way, so if you are a fan of this approach - it will work (like in "Hello Express" example above).

Still if you want to benefit from asynchronicity, we provide a very powerful API set that accepts futures as result of your handler.

Let's assume you have following function somewhere:

func calcFactorial(num:Double) -> Future<Double, AnyError>

it's a purely asyncronous function that returns future. It would be really nice if it could be handled asynchronously as well in a nice functional way. Here is an example of how it could be done.

// (request -> Future<Action<AnyContent>, AnyError> in) - this is required to tell swift you want to return a Future
// hopefully inference in swift will get better eventually and just "request in" will be enough
app.get("/factorial/:num(\\d+)") { request -> Future<Action<AnyContent>, AnyError> in
    // get the number from the url
    let num = request.params["num"].flatMap{Double($0)}.getOrElse(0)
    
    // get the factorial Future. Returns immediately - non-blocking
    let factorial = calcFactorial(num)
    
    //map the result of future to Express Action
    let future = factorial.map { fac in
        Action.ok(String(fac))
    }
    
    //return the future
    return future
}

URL params

Let's get our echo example from Getting Started a bit further. Our routing engine, which is largely based on NodeJS analog path-to-regex. You can read the complete documentation on how to use path patterns here. Now an example with URL param:

//:param - this is how you define a part of URL you want to receive through request object
app.get("/echo/:param") { request in
    //here you get the param from request: request.params["param"]
    .ok(request.params["param"])
}

Serving static files

app.get("/:file+", action: StaticAction(path: "public", param:"file"))

The code above tells Express to serve all static files from the public folder recursively. If you want to serve just the first level in folder, use:

app.get("/:file", action: StaticAction(path: "public", param:"file"))

The difference is just in the pattern: /:file versus /:file+. For more information see our routing section.

Serving JSON requests

First of all we need to register the JSON view in the system:

//now we can refer to this view by name
app.views.register(JsonView())

Let's say we want to build a simple API for users registration. We want our API consumers to POST to /api/user a JSON object and get a JSON response back.

app.post("/api/user") { request in
    //check if JSON has arrived
    guard let json = request.body?.asJSON() else {
        return Action.ok("Invalid request")
    }
    //check if JSON object has username field
    guard let username = json["username"].string else {
        return Action.ok("Invalid request")
    }
    //compose the response as a simple dictionary
    let response =
        ["status": "ok",
        "description": "User with username '" + username + "' created succesfully"]
    
    //render disctionary as json (remember the one we've registered above?)
    return .render(JsonView.name, context: response)
}

Lines above will do the job. Post this JSON:

{
    "username": "swiftexpress"
}

to our api URL: http://localhost:9999/api/user (don't forget application/json content type header) and you will get this response:

{
  "status": "ok",
  "description": "User with username 'swiftexpress' created succesfully"
}

Using template engine

First of all you need to switch the template engine on:

//we recommend mustache template engine
app.views.register(StencilViewEngine())

Now create a file called hello.stencil in the views directory:

<html>
<body>
<h1>Hello from Stencil: {{user}}</h1>
</body>
</html>

Add a new request handler:

//user as an url param
app.get("/hello/:user.html") { request in
    //get user
    let user = request.params["user"]
    //if there is a user - create our context. If there is no user, context will remain nil
    let context = user.map {["user": $0]}
    //render our template named "hello"
    return .render("hello", context: context)
}

Now follow the link to see the result: http://localhost:9999/hello/express.html

If you want more, please, visit our documentation page

Ideology behind

Taking the best of Swift

Swift essentially is a new generation programming language combining simplicity and all the modern stuff like functional programming.

We were inspired (and thus influenced) mainly by two modern web frameworks: Express.js and Play. So, we are trying to combine the best of both worlds taking simplicity from Express.js and modern robust approach of Play

Let us know if we are on the right path! Influence the project, create feature requests, API change requests and so on. While we are in our early stages, it's easy to change. We are open to suggestions!

Features

And heah, the most important feature: Highly passionate development team

Roadmap

  • v0.4: stable version with Swift 3.0
  • v0.5: proper streaming
  • v0.6: new core (based on Reactive Swift)
  • v0.7: more content types available out of the box
  • v0.8: Web Sockets
  • v0.9: hot code reload
  • v1.0: hit the production!

Changelog

  • v0.4: Swift 3.0

  • v0.3: linux support

  • v0.2.1: minor changes

    • Swift modules are installed via Carthage
    • Enabled binary builds on OS X
  • v0.2: Solid OS X release

    • Much better routing APIs
    • Advanced routing path patterns
    • Possibility to use Regex for routing
    • Greately improved README
    • Some bugfixes
  • v0.1: Initial Public Release

    • basic routing
    • views and view engines (supports Mustache)
    • JSON rendering as a view
    • query parsing
    • static files serving

Contributing

To get started, sign the Contributor License Agreement.

Crossroad Labs by Crossroad Labs

Comments
  • Cannot build Express on Linux and MAC OS X using the latest Swift 2.2 or Swift 3.0 and SPM

    Cannot build Express on Linux and MAC OS X using the latest Swift 2.2 or Swift 3.0 and SPM

    The express does not build on Linux nor Mac OS X using the latest Swift Development snapshots (2.2 or 3.0). Also the SPM build does not work either with the provided Package.swift file.

    question 
    opened by ilap 9
  • Unresolved identifiers issue

    Unresolved identifiers issue

    I faced following error while running HelloWorld example.

    /home/ubuntu/Projects/Project7/Packages/ExecutionContext-0.3.1/ExecutionContext/ExecutionContext.swift:162:15: error: use of unresolved identifier 'time_t'
        let sec = time_t(timeout)
                  ^~~~~~
    /home/ubuntu/Projects/Project7/Packages/ExecutionContext-0.3.1/ExecutionContext/ExecutionContext.swift:164:16: error: use of unresolved identifier 'time spec'
        var time = timespec(tv_sec:sec, tv_nsec: nsec)
                   ^~~~~~~~
    /home/ubuntu/Projects/Project7/Packages/ExecutionContext-0.3.1/ExecutionContext/ExecutionContext.swift:166:5: error: use of unresolved identifier 'nano sleep'
        nanosleep(&time, nil)
        ^~~~~~~~~
    <unknown>:0: error: build had 1 command failures
    error: exit(1): ["/home/ubuntu/swift/swift2.2/usr/bin/swift-build-tool", "-f", "/home/ubuntu/Projects/Project7/.build/debug/ExecutionContext.o/llbuild.yaml"]
    
    opened by HarshitDaftary 9
  • build dispatch failed issue for missing pthread_workqueue.h and its solution on Linux

    build dispatch failed issue for missing pthread_workqueue.h and its solution on Linux

    On Ubuntu15.10, we also need another command to make a success on build dispatch sudo apt-get install libpthread-workqueue-dev

    and then ,build dispatch will succeed

    Thanks

    opened by learningpro 4
  • Error on: swift-express init HelloExpress

    Error on: swift-express init HelloExpress

    Hello,

    I've tried getting started on El Capitain, but got this error after issuing swift-express init HelloExpress:

    CompileSwift normal x86_64 /Users/kdreiners/HelloExpress/Carthage/Checkouts/Express/Express/Transaction.swift CompileSwift normal x86_64 /Users/kdreiners/HelloExpress/Carthage/Checkouts/Express/Express/Static.swift CompileSwift normal x86_64 /Users/kdreiners/HelloExpress/Carthage/Checkouts/Express/Express/ErrorHandler.swift CompileSwift normal x86_64 /Users/kdreiners/HelloExpress/Carthage/Checkouts/Express/Express/ExpressSugar.swift CompileSwiftSources normal x86_64 com.apple.xcode.tools.swift.compiler (5 failures) /Users/kdreiners/HelloExpress/Carthage/Checkouts/Express/Modules/CPthread/module.map:23:9: error: header '/usr/include/pthread.h' not found /Users/kdreiners/HelloExpress/Carthage/Checkouts/Express/Express/HttpServer.swift:24:8: error: could not build Objective-C module 'CPThread' /Users/kdreiners/HelloExpress/Carthage/Checkouts/Express/Modules/CPthread/module.map:23:9: error: header '/usr/include/pthread.h' not found /Users/kdreiners/HelloExpress/Carthage/Checkouts/Express/Express/HttpServer.swift:24:8: error: could not build Objective-C module 'CPThread' /Users/kdreiners/HelloExpress/Carthage/Checkouts/Express/Modules/CPthread/module.map:23:9: error: header '/usr/include/pthread.h' not found /Users/kdreiners/HelloExpress/Carthage/Checkouts/Express/Express/HttpServer.swift:24:8: error: could not build Objective-C module 'CPThread' /Users/kdreiners/HelloExpress/Carthage/Checkouts/Express/Modules/CPthread/module.map:23:9: error: header '/usr/include/pthread.h' not found /Users/kdreiners/HelloExpress/Carthage/Checkouts/Express/Express/HttpServer.swift:24:8: error: could not build Objective-C module 'CPThread' A shell task failed with exit code 65:

    Thanks in advance

    Best

    Klaus-Dieter

    opened by KDReiners 4
  • launch path not accessible

    launch path not accessible

    I followed the instructions in the readme and swift-express run fails.

    OS 10.11.4 xcode 7.3

    $ swift-express run Running cxo-report-generator... Unhandled error in RunStep. Error: SubtaskError("Task launch error: launch path not accessible") Subtask Error: Task launch error: launch path not accessible

    opened by mlabs-jay 3
  • Any idea about Nimble problem ?

    Any idea about Nimble problem ?

    Hello Guys,

    I have tried tree different machine. I have always taken same error message below.

    brew install swift-express ==> Installing swift-express from crossroadlabs/tap ==> Cloning https://github.com/crossroadlabs/ExpressCommandLine.git Updating /Library/Caches/Homebrew/swift-express--git ==> Checking out tag 0.2.1 ==> carthage update --platform Mac Last 15 lines from /Users/duruldalkanat/Library/Logs/Homebrew/swift-express/01.carthage: The following build commands failed: CompileSwift normal x86_64 /tmp/swift-express20160324-691-1jkr1m1/Carthage/Checkouts/Commandant/Carthage/Checkouts/Nimble/Nimble/Adapters/NimbleXCTestHandler.swift CompileSwiftSources normal x86_64 com.apple.xcode.tools.swift.compiler (2 failures)

    *** Fetching Regex *** Fetching Commandant *** Fetching Result *** Checking out Commandant at "0.8.3" *** Checking out SwiftTryCatch at "af21e8f91cd994a8ea459540f922f0e5e1c57618" *** Downloading Regex.framework binary at "v0.4.1: optional groups support" *** Downloading Result.framework binary at "1.0.2: A Swift Result" *** xcodebuild output can be found in /var/folders/nz/f5vmppwd7kg44qt1xsdk_b_m0000gn/T/carthage-xcodebuild.Fw3Nwo.log *** Building scheme "Commandant" in Commandant.xcworkspace *** Building scheme "Nimble-OSX" in Commandant.xcworkspace

    bug 
    opened by durul 3
  • Build HelloExpress example failed because of git clone a package called Result

    Build HelloExpress example failed because of git clone a package called Result

    I do just as the document said, write a Package.swift import PackageDescription

    let package = Package( name: "HelloExpress", dependencies: [ .Package(url: "https://github.com/crossroadlabs/Express.git", majorVersion: 0, minor: 3), ] )

    but when I run ./build , it clones many repo and finally failed with a message called

    error: Failed to clone https://github.com/antitypical/Result.git Packages/Result' already exists and is not an empty directory.

    I want to know why there are so many packages even the Package.swift uses only one, and why the Reault package comes into failure.

    opened by learningpro 2
  • Failed to discover shared schemes in project MustacheDemoiOS7.xcodeproj

    Failed to discover shared schemes in project MustacheDemoiOS7.xcodeproj

    *** Cloning Box Failed to discover shared schemes in project MustacheDemoiOS7.xcodeproj—either the project does not have any shared schemes, or xcodebuild never returned

    opened by deapamukchieva 1
  • ** BUILD FAILED ** after

    ** BUILD FAILED ** after "swift-express bootstrap" command

    I am getting this error after running the command:

    swift-express bootstrap
    

    Error:

    ** BUILD FAILED **
    
    
    The following build commands failed:
        CompileSwift normal x86_64 /Users/Moi/Desktop/Swift Express/HelloExpress/Carthage/Checkouts/Result/Result/ResultType.swift
        CompileSwift normal x86_64 /Users/Moi/Desktop/Swift Express/HelloExpress/Carthage/Checkouts/Result/Result/Result.swift
        CompileSwiftSources normal x86_64 com.apple.xcode.tools.swift.compiler
    (3 failures)
    
    Subtask Error: CarthageInstallLibs: bootstrap failed. Exit code 1
    
    bug duplicate 
    opened by moyoteg 1
  • Express v0.4

    Express v0.4

    I don't see any activity for the last 6 months in the repo. Is v0.4 being worked on? Any idea when it will be out (and working with Linux/Swift 3) ?

    This is a great project and very needed - I'd be interested if you need help

    opened by bertbeck 5
  • Refresh view after async response

    Refresh view after async response

    When I render a view and call some async API how do I update that view? I could not find any reload/refresh methods in the docs. For example:

    app.get("/home") { request in
        HomeController().fetchData { posts in  
           // Update view with response 
        }
        return HomeController.index("/home")
    }
    
    question 
    opened by newPrimitives 4
  • New logo

    New logo

    This logo uses same font as express.js does. The gradient uses the same color scheme as the Swift logo does. Readme is tidied up a bit as well making this project more approachable.

    opened by hfossli 7
Releases(0.3.6)
Owner
Crossroad Labs
Crossroad Labs s.r.o.
Crossroad Labs
💧 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
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
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
High Performance (nearly)100% Swift Web server supporting dynamic content.

Dynamo - Dynamic Swift Web Server Starting this project the intention was to code the simplest possible Web Server entirely in Swift. Unfortunately I

John Holdsworth 68 Jul 25, 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
QwikHttp is a robust, yet lightweight and simple to use HTTP networking library for iOS, tvOS and watchOS

QwikHttp is a robust, yet lightweight and simple to use HTTP networking library. It allows you to customize every aspect of your http requests within a single line of code, using a Builder style syntax to keep your code super clean.

Logan Sease 2 Mar 20, 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
An elegant yet powerful iOS networking layer inspired by ActiveRecord.

Written in Swift 5 AlamoRecord is a powerful yet simple framework that eliminates the often complex networking layer that exists between your networki

Tunespeak 19 Nov 19, 2022
Rayon - Yet another SSH machine manager for macOS

Rayon A server monitor tool for linux based machines using remote proc file syst

Lakr Aream 2.3k Jan 8, 2023
A simple GCD based HTTP client and server, written in 'pure' Swift

SwiftyHTTP Note: I'm probably not going to update this any further - If you need a Swift networking toolset for the server side, consider: Macro.swift

Always Right Institute 116 Aug 6, 2022
A simple HTTP server written in Swift

http4swift http4swift is a tiny HTTP server library for Nest-compatible applications. This project is unstable, and the API might be changed at anytim

Shun Takebayashi 27 Jun 29, 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, 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
Robust Swift networking for web APIs

Conduit Conduit is a session-based Swift HTTP networking and auth library. Within each session, requests are sent through a serial pipeline before bei

Mindbody 52 Oct 26, 2022
A Ruby on Rails inspired Web Framework for Swift that runs on Linux and OS X

IMPORTANT! We don't see any way how to make web development as great as Ruby on Rails or Django with a very static nature of current Swift. We hope th

Saulius Grigaitis 2k Dec 5, 2022
A lightweight library for writing HTTP web servers with Swift

Taylor Disclaimer: Not actively working on it anymore. You can check out some alternatives Swift 2.0 required. Working with Xcode 7.1. Disclaimer: It

Jorge Izquierdo 925 Nov 17, 2022
Frank is a DSL for quickly writing web applications in Swift

Frank Frank is a DSL for quickly writing web applications in Swift with type-safe path routing. Sources/main.swift import Frank // Handle GET request

Kyle Fuller Archive 377 Jun 29, 2022
A Swift Multiplatform Single-threaded Non-blocking Web and Networking Framework

Serverside non-blocking IO in Swift Ask questions in our Slack channel! Lightning (formerly Edge) Node Lightning is an HTTP Server and TCP Client/Serv

SkyLab 316 Oct 6, 2022
Super lightweight web framework in Swift based on SWSGI

Ambassador Super lightweight web framework in Swift based on SWSGI Features Super lightweight Easy to use, designed for UI automatic testing API mocki

Envoy 170 Nov 15, 2022