Swiftpack.co - Package - vapor/vapor


Documentation Slack Team MIT License Continuous Integration Swift 3.1 Twitter

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

💧 Community

Join the welcoming community of fellow Vapor developers in slack.

🚀 Contributing

All developers should feel welcome and encouraged to contribute to Vapor, see our getting started document here to get involved.

To contribute a feature or idea to Vapor, submit an issue and fill in the template. If the request is approved, you or one of the members of the community can start working on it.

If you find a bug, please submit a pull request with a failing test case displaying the bug or create an issue.

If you find a security vulnerability, please contact security@vapor.codes as soon as possible. We take these matters seriously.

💙 Code of Conduct

Our goal is to create a safe and empowering environment for anyone who decides to use or contribute to Vapor. Please help us make the community a better place by abiding to this Code of Conduct during your interactions surrounding this project.

🏫 Tutorials

The awesome Vapor community is always adding new tutorials and articles out there, Vapor University is a great place to get started!

👥 Backers

Support us with a monthly donation and help us continue our activities. [Become a backer]

🥇 Sponsors

Proudly sponsored by Nodes (🏅), Skelpo (🥉), and our Open Collective sponsors.


Michael Dominick



Stars: 12398
Help us keep the lights on


2.4.2 - Dec 21, 2017


  • .decodeJSONBody now accepts an explicit type parameter.
let model = try request.decodeJSONBody(TestModel.self)


2.4.1 - Dec 21, 2017


  • Remove Swift warnings.


3.0.0-beta.1 - Dec 19, 2017

⚠️ It looks like SPM has issues resolving dependencies if you rely on this beta tag directly. Instead, rely on .branch("beta") and optionally use this Package.resolved file for specifically the beta.1 dependencies.

🎉 The first beta of Vapor 3.0 is here!

There have been some massive internal updates between Alpha 12 and Beta 1, but for the most part the public API is unchanged. Due to the internal changes, we are looking out for regressions from Alpha 12 to Beta 1. If you find any, please report and we will work quickly to resolve them.


  • Reactive Streams: Vapor's internal async streams now support back-pressure.

Reactive streams means your Vapor applications will be more resilient to the producer-consumer problem that has long plagued web applications. Vapor achieves this by moving from "push" streams (aka, fire hose streams) to "pull" streams. At a high level, this means better performance and less memory usage during peak demand.

Learn more at reactive-streams.org.

  • Kqueue: Vapor now uses Kqueue under the hood instead of Dispatch. This yielded a 30% improvement in raw TCP performance. Epoll support for Linux coming soon.
  • Module separation: Vapor 3's source code has been put back to its original repos. Please file future issues on the repos to which they pertain.
  • Key String Map: Key string maps are no longer required on Fluent models thanks to a custom built decoder for deriving [CodingKey] paths from Swift KeyPaths.
  • Migrations: Migrations are no longer required when added to Fluent models thanks to another custom built decoder for discovering all model properties.
  • Terminal Styles: Several new terminal style options have been added to the Console package.
  • Future chaining: We have updated Future chaining methods to better match Swift.

futureString.map(to: T.self) accepts a (String) -> T

let futureString = futureInt.map(to: String.self) { $0.description }

futureString.flatMap(to: T.self) accepts a (String) -> Future<T>

let futureResponse = futureString.flatMap(to: Response.self) { string in
    return client.get(string)
  • Removed some .register overloads from the Services struct. Registering instances of services and providers now have their own methods.
var services = Services.default()

/// instance
let myFoo = Foo()

/// provider
try services.provider(FooProvider())

/// factory
services.register { container in
    return Foo()


  • Services now properly respect tags.

3.0.0-alpha.12 - Dec 6, 2017

🍾 This is our 200th release!

Compare 3.0.0-alpha.11...3.0.0-alpha.12

161 changed files with 1,735 additions and 840 deletions.


  • New Validation module.
import Validation

let user = User(...)
try user.validate()
final class User: Validatable {
    var id: Int?
    var name: String
    var age: Int
    var child: User?

    init(id: Int? = nil, name: String, age: Int) {
        self.id = id
        self.name = name
        self.age = age

    static var keyStringMap: KeyStringMap = [
        key(\.id): "id",
        key(\.name): "name",
        key(\.age): "age",
        key(\.child): "child"

    static var validations: Validations = [
        key(\.id): !IsNil(), // ensures id is not nil
        key(\.name): IsCount(5...), // ensures name is at least 5 chars
        key(\.age): IsCount(3...), // ensures age is above or equal to 3
        key(\.child): IsNil() || IsValid() // ensures child user is either nil or validates it
  • Renamed some generic modules to avoid future collisions (Core -> JunkDrawer, libc -> COperatingSystem)
  • Adds Base64URL encoding/decoding
  • Refactored JWT
struct TestPayload: JWTPayload {
    var sub: SubjectClaim
    var name: String
    var admin: Bool
    var exp: ExpirationClaim

    func verify() throws {
        try exp.verify()
let data = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImV4cCI6OTk5OTk5OTk5OTk5fQ.Ks7KcdjrlUTYaSNeAO5SzBla_sFCHkUh4vvJYn6q29U"

let signer = JWTSigner.hs256(key: Data("secret".utf8))
let jwt = try JWT<TestPayload>(from: data, verifiedUsing: signer)
XCTAssertEqual(jwt.payload.name, "John Doe")
XCTAssertEqual(jwt.payload.sub.value, "1234567890")
XCTAssertEqual(jwt.payload.admin, true)
  • Environment.get("FOO") for getting process env variables


  • Publicized import Multipart
  • --env flag is now supported
  • Simplified TCP socket connect, fixing some intermittent errors

3.0.0-alpha.11 - Dec 5, 2017

Compare 3.0.0-alpha.x to 3.0.0-alpha.11

82 changed files with 1,676 additions and 816 deletions.


  • FileMiddleware has been implemented.
  • Fluent now supports omitting types in filter methods
User.query(on: req).filter(\.name == "Vapor")
  • EngineClient and Client protocol have been added.
let res = req.make(Client.self).send(.get, to: "http://vapor.codes")
  • LeafData is now wrapped in a reference based LeafContext allowing nested #set
  • Add convenience subscript getters to req.query and req.content for decoding single values
// query
let test: String? = req.query["hello"]

// content
XCTAssertEqual(req.content["batters", "batter", 1, "type"], "Chocolate")
  • New req.streamFile(at: String) function for creating a streaming file response
  • Convenience accessors for URI, headers, body, etc on Vapor.Request
  • Core.File now supports streaming.
  • HTTPServer now supports a generic stream type instead of concrete TCP socket.
  • DataCoder is now BodyCoder


  • String and Int now encode to plaintext instead of html by default.
  • Authentication issues with MySQL on Linux.
  • FormURLEncoded target.
  • Fixes the regression for WebSocket routes not passing the Vapor.Request