Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Swift in the Cloud

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers.

Swift in the Cloud

Talk given at AKIBA.swift on April 28, 2016.

In this talk, I go through the steps it takes to get a web server running in Swift. I go through some of the more popular frameworks that are available, and what I thought about them.

Avatar for Caesar Wirth

Caesar Wirth

April 27, 2016
Tweet

More Decks by Caesar Wirth

Other Decks in Technology

Transcript

  1. CAESAR WIRTH CYBERAGENT, INC. > Current: AbemaTV > Swift since

    August 2014 > try! Swift Organizer and Speaker
  2. STEPS TO SERVER SIDE SWIFT 1. Set up your Environment

    2. Choose a Framework 3. Conform to Standards 4. Deploy!
  3. Nothing is Stable So use tools to make it better

    > swiftenv > Swift Package Manager
  4. SWIFTENV Swift Version Manager > Easily install latest releases and

    snapshots > Project Scoped: ./swift-version > chswift is probably OK too
  5. SWIFTENV # Official Releases > swiftenv install 2.2 # Snapshots

    > swiftenv install DEVELOPMENT-SNAPSHOT-2016-04-12-a # Scoped > swiftenv local DEVELOPMENT-SNAPSHOT-2016-03-24-a > swiftenv global 2.2
  6. SWIFT PACKAGE MANAGER Dependency Manager > Included in Swift Toolchain

    > Fetches and builds depencencies from git > Needs a Package.swift
  7. SWIFT PACKAGE MANAGER - PACKAGE.SWIFT import PackageDescription let package =

    Package( name: "swift-api-server", dependencies: [ .Package(url: "https://github.com/user/server.git", majorVersion: 0, minor: 9) ] )
  8. . !"" .build # $"" debug # $"" Build Files,

    Including Binary !"" Package.swift !"" Packages # $"" Downloaded Dependencies !"" Sources # !"" Module # # $"" Module Sources # $"" main.swift $"" Tests !"" Module # $"" Tests for Module $"" Test Files For Package
  9. NEW IN SPM: swift build -X Generates Xcode Project SPM

    ❤ Xcode My blog post post is deprecated
  10. AWESOME-SWIFT#WEBSERVER - Aeon - Perfect - Curassow - Swifty-Server -

    Blackfish - swifter - Dynamo - SwiftyHTTP - Express - Swifton - Frank - Taylor - http4swift - Trevi - Kitura - Vapor - Kunugi - XcodeServerSDK - NetworkObjects - Zewo
  11. PERFECT Easy setup Database Support: SQLite, MySQL, PostreSQL, MongoDB Uses

    Swifty Features Feature rich, but with boilerplate
  12. // PerfectLib public protocol RequestHandler { func handleRequest(request: WebRequest, response:

    WebResponse) } // MyApp public func PerfectServerModuleInit() { RoutingHandler.registerGlobally() Routing.Routes["GET", "/users/{id}"] = { _ in return FetchUserHandler() } } class FetchUserHandler: RequestHandler { func handleRequest(request: WebRequest, response: WebResponse) { let user: String = response.urlVariables["id"] ?? "No User" response.appendBodyString("You selected user: \(user)") response.requestCompletedCallback() } }
  13. import Kitura let router = Router() router.get("/users/:user") { request, response,

    next in let user = request.params["user"] ?? "No User" do { response.status(HttpStatusCode.OK) response.send("You selected user: \(user)") try response.end() } catch { print("Error with request: \(error)") } } let server = HttpServer.listen(8090, delegate: router) Server.run() // Just runs the main run loop
  14. import HTTPServer import Router let router = Router { route

    in route.get("/users/:user") { request in let user = request.pathParameters["user"] ?? "No User" return Response(body: "You selected user: \(user)") } } try Server(responder: router).start()
  15. import Vapor let app = Application() app.get("users", String.self) { request,

    user in return "You selected user: \(user)" } app.start(port: 8888)
  16. WEB SERVER GATEWAY INTERFACE > Python has WSGI > Ruby

    has Rack > Perl has PSGI > Swift has...
  17. NEST - Swift Web Server Gateway Interface - Minimal interface

    between web servers and web applications - Very Simple Spec
  18. /// Represents a HTTP Header, Key and Value public typealias

    Header = (String, String) /// Represents a HTTP request or response body public protocol PayloadType { /// Returns the next byte in the payload mutating func next() -> [UInt8]? } /// Represents a HTTP Request public protocol RequestType { var method:String { get } var path:String { get } var headers:[Header] { get } var body: PayloadType? { get set } } /// Represents a HTTP Response public protocol ResponseType { var statusLine:String { get } var headers:[Header] { get } var body: PayloadType? { get set } } public typealias Application = RequestType -> ResponseType
  19. OPENSWIFT - Open source cross project standards for Swift -

    Different project for different standards - S4 - HTTP Standards - C7 - Core Standards - D5 - Database Standards - Very Comprehensive Spec
  20. DEPLOYING TO HEROKU 1. Download heroku-buildpack-swift 2. Set your swift-version

    3. Create Procfile 4. Get port from command line 5. Push to Heroku!
  21. 1 BUILDPACK SETUP # Install Heroku CLI. Also need to

    do login and stuff > brew install heroku-toolbelt # Set the buildpack for your application > heroku buildpacks:set https://github.com/kylef/heroku-buildpack-swift.git # Set the swift-version for this project > swiftenv local DEVELOPMENT-SNAPSHOT-2016-04-12-a # Create Procfile to fetch port from command line > echo "web: AKIBA.vapor --port=$PORT" > Procfile
  22. 2 CONFIGURE PORT FROM ARGUMENTS // Process.valueFor() is a Vapor-provided

    method // Can also search through the `Process.arguments` array let portArg = Process.valueFor(argument: "port") ?? "8888" let port = Int(portArg) ... print("Running on port: \(port)") app.start(port: port)
  23. 3 PUSH TO HEROKU > git commit -am "Prepare for

    Deploy" > git push heroku master