All Projects → crossroadlabs → Express

crossroadlabs / Express

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

Programming Languages

swift
15916 projects

Projects that are alternatives of or similar to Express

Newbe.claptrap
This is a frameworks with reactive, event sourcing and Actor pattern as basic theories. On top of this, developers can create "distributed", "scale out", and "easy to test" application more simply. Claptrap and it`s Minions is on the way.
Stars: ✭ 163 (-80.94%)
Mutual labels:  reactive, server
futura
Asynchronous Swift made easy. The project was made by Miquido. https://www.miquido.com/
Stars: ✭ 34 (-96.02%)
Mutual labels:  reactive, asynchronous
Play Ws
Standalone Play WS, an async HTTP client with fluent API
Stars: ✭ 190 (-77.78%)
Mutual labels:  reactive, asynchronous
Swiftlysalesforce
The swiftest way to build iOS apps that connect to Salesforce
Stars: ✭ 115 (-86.55%)
Mutual labels:  reactive, asynchronous
Cloe
Cloe programming language
Stars: ✭ 398 (-53.45%)
Mutual labels:  reactive, asynchronous
Vertx Mqtt
Vert.x MQTT
Stars: ✭ 117 (-86.32%)
Mutual labels:  reactive, server
Smallrye Mutiny
An Intuitive Event-Driven Reactive Programming Library for Java
Stars: ✭ 231 (-72.98%)
Mutual labels:  reactive, asynchronous
Jdonframework
Domain-Driven-Design Pub/Sub Domain-Events framework
Stars: ✭ 978 (+14.39%)
Mutual labels:  reactive, asynchronous
Lettuce Core
Advanced Java Redis client for thread-safe sync, async, and reactive usage. Supports Cluster, Sentinel, Pipelining, and codecs.
Stars: ✭ 4,319 (+405.15%)
Mutual labels:  reactive, asynchronous
Reactor Core
Non-Blocking Reactive Foundation for the JVM
Stars: ✭ 3,891 (+355.09%)
Mutual labels:  reactive, asynchronous
Rdbc
Asynchronous database access for Scala and Java
Stars: ✭ 78 (-90.88%)
Mutual labels:  reactive, asynchronous
Reactivemongo
🍃 Non-blocking, Reactive MongoDB Driver for Scala
Stars: ✭ 825 (-3.51%)
Mutual labels:  reactive, asynchronous
Cyclops
An advanced, but easy to use, platform for writing functional applications in Java 8.
Stars: ✭ 1,180 (+38.01%)
Mutual labels:  reactive, asynchronous
Play Redis
Play framework 2 cache plugin as an adapter to redis-server
Stars: ✭ 152 (-82.22%)
Mutual labels:  reactive, asynchronous
Rocket.jl
Functional reactive programming extensions library for Julia
Stars: ✭ 69 (-91.93%)
Mutual labels:  reactive, asynchronous
Flow
Flow is a Swift library for working with asynchronous flows and life cycles
Stars: ✭ 225 (-73.68%)
Mutual labels:  reactive, asynchronous
Lear
Linux Engine for Asset Retrieval - speed-profiled C HTTP server
Stars: ✭ 165 (-80.7%)
Mutual labels:  asynchronous, server
Tarant
Reactive, actor based framework that can be used in client and server side.
Stars: ✭ 33 (-96.14%)
Mutual labels:  reactive, asynchronous
Firefly
Firefly is an asynchronous web framework for rapid development of high-performance web application.
Stars: ✭ 277 (-67.6%)
Mutual labels:  reactive, asynchronous
Reactivemanifesto
The Reactive Manifesto
Stars: ✭ 542 (-36.61%)
Mutual labels:  reactive, asynchronous

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

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].