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
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
💧 A server-side Swift HTTP web framework.

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

Vapor 22.4k Jan 3, 2023
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
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 Dec 27, 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
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
A light-weight server-side service framework written in the Swift programming language.

Smoke Framework The Smoke Framework is a light-weight server-side service framework written in Swift and using SwiftNIO for its networking layer by de

Amazon 1.4k Dec 22, 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 Jan 5, 2023
Simple server APIs in Swift

Simple server APIs in Swift

null 4 Apr 25, 2022
Sinatra-like DSL for developing web apps in Swift

Swiftra Swiftra is a library that provides DSLs like Sinatra. System Requirements DEVELOPMENT-SNAPSHOT-2016-02-08-a Example See swiftra-example. impor

Shun Takebayashi 262 Jun 29, 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 376 Jan 3, 2023
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 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
Server-side Swift. The Perfect core toolset and framework for Swift Developers. (For mobile back-end development, website and API development, and more…)

Perfect: Server-Side Swift 简体中文 Perfect: Server-Side Swift Perfect is a complete and powerful toolbox, framework, and application server for Linux, iO

PerfectlySoft Inc. 13.9k Dec 29, 2022
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
Swift HTTP server using the pre-fork worker model

Curassow Curassow is a Swift Nest HTTP Server. It uses the pre-fork worker model and it's similar to Python's Gunicorn and Ruby's Unicorn. It exposes

Kyle Fuller Archive 397 Oct 30, 2022
Reliable Server Side Swift ✭ Make Apache great again!

mod_swift mod_swift is a technology demo which shows how to write native modules for the Apache Web Server in the Swift 3 programming language. The de

The ApacheExpress Alliance 174 Oct 22, 2022
Super lightweight async HTTP server library in pure Swift runs in iOS / MacOS / Linux

Embassy Super lightweight async HTTP server in pure Swift. Please read: Embedded web server for iOS UI testing. See also: Our lightweight web framewor

Envoy 540 Dec 15, 2022