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


Become a sponsor and get your logo on our README on GitHub with a link to your site. [Become a sponsor]

Michael Dominick



Stars: 11987
Help us keep the lights on


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

3.0.0-alpha.x - Dec 1, 2017


  • Authentication package. Includes PasswordAuthenticatable and middleware. See AuthenticationTests for info on how to use.
  • uppercase, and capitalize Leaf tags.
  • ConsoleLogger and PrintLogger in Logging package. let logger = try app.make(Logger.self)


  • Singleton services should now work properly
  • count leaf tag now works properly

3.0.0-alpha.8 - Dec 1, 2017

  • Removes the need for providing an eventloop to leaf's make() function
  • Fixes a routing regression bug
  • Fluent now properly updated the id for entities
  • MySQL is between 50% and 80% faster
  • HTTP is 30% faster
  • General cleanup/householding

3.0.0-alpha.7 - Dec 1, 2017

  • Expose the FluentMySQL library