Slide 1

Slide 1 text

AKIBA.SWIFT - APRIL 26, 2016 SWIFT IN THE CLOUD CAESAR WIRTH

Slide 2

Slide 2 text

CAESAR WIRTH CYBERAGENT, INC. > Current: AbemaTV > Swift since August 2014 > try! Swift Organizer and Speaker

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

STEPS TO SERVER SIDE SWIFT 1. Set up your Environment 2. Choose a Framework 3. Conform to Standards 4. Deploy!

Slide 6

Slide 6 text

1. SET UP YOUR ENVIRONMENT!

Slide 7

Slide 7 text

Nothing is Stable So use tools to make it better > swiftenv > Swift Package Manager

Slide 8

Slide 8 text

SWIFTENV Swift Version Manager > Easily install latest releases and snapshots > Project Scoped: ./swift-version > chswift is probably OK too

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

SWIFT PACKAGE MANAGER Dependency Manager > Included in Swift Toolchain > Fetches and builds depencencies from git > Needs a Package.swift

Slide 11

Slide 11 text

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) ] )

Slide 12

Slide 12 text

. !"" .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

Slide 13

Slide 13 text

NEW IN SPM: swift build -X

Slide 14

Slide 14 text

NEW IN SPM: swift build -X Generates Xcode Project SPM ❤ Xcode My blog post post is deprecated

Slide 15

Slide 15 text

2. CHOOSE A FRAMEWORK!

Slide 16

Slide 16 text

AWESOME-SWIFT#WEBSERVER - Aeon - Perfect - Curassow - Swifty-Server - Blackfish - swifter - Dynamo - SwiftyHTTP - Express - Swifton - Frank - Taylor - http4swift - Trevi - Kitura - Vapor - Kunugi - XcodeServerSDK - NetworkObjects - Zewo

Slide 17

Slide 17 text

No content

Slide 18

Slide 18 text

1. Perfect - 6,972⭐ 2. Vapor - 3,613⭐ 3. Kitura - 2,880⭐ 4. Zewo - 945⭐

Slide 19

Slide 19 text

PERFECT Easy setup Database Support: SQLite, MySQL, PostreSQL, MongoDB Uses Swifty Features Feature rich, but with boilerplate

Slide 20

Slide 20 text

// 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() } }

Slide 21

Slide 21 text

KITURA Modular Database Support: Redis, CouchDB Good Documentation Lightweight Setup Good so far, looking forward to it

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

ZEWO Server Set of Libraries Lots of modules More than just web APIs One-stop toolbox

Slide 24

Slide 24 text

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()

Slide 25

Slide 25 text

VAPOR Made with parts of Zewo Type-safe URL parameters Easy to work with My personal favorite !

Slide 26

Slide 26 text

import Vapor let app = Application() app.get("users", String.self) { request, user in return "You selected user: \(user)" } app.start(port: 8888)

Slide 27

Slide 27 text

Use whichever you like best !

Slide 28

Slide 28 text

3. CONFORM TO STANDARDS!

Slide 29

Slide 29 text

Separate your APPLICATION From your SERVER

Slide 30

Slide 30 text

WEB SERVER GATEWAY INTERFACE > Python has WSGI > Ruby has Rack > Perl has PSGI > Swift has...

Slide 31

Slide 31 text

WEB SERVER GATEWAY INTERFACE > Nest > OpenSwift

Slide 32

Slide 32 text

NEST - Swift Web Server Gateway Interface - Minimal interface between web servers and web applications - Very Simple Spec

Slide 33

Slide 33 text

/// 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

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

No content

Slide 36

Slide 36 text

STANDARDS == FLEXIBILITY

Slide 37

Slide 37 text

4. DEPLOY!

Slide 38

Slide 38 text

DOCKER OR HEROKU

Slide 39

Slide 39 text

I've never actually used Docker !

Slide 40

Slide 40 text

HEROKU

Slide 41

Slide 41 text

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!

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

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)

Slide 44

Slide 44 text

3 PUSH TO HEROKU > git commit -am "Prepare for Deploy" > git push heroku master

Slide 45

Slide 45 text

4 PRAY

Slide 46

Slide 46 text

> curl http://akiba-swift-caesar.herokuapp.com/

Slide 47

Slide 47 text

> curl http://akiba-swift-caesar.herokuapp.com/ Hello, World!

Slide 48

Slide 48 text

No content

Slide 49

Slide 49 text

THANK YOU!

Slide 50

Slide 50 text

FURTHER READING https://swiftenv.fuller.li/en/latest/ http://perfect.org/ https://github.com/IBM-Swift/Kitura http://vapor.qutheory.io/ https://github.com/nestproject https://github.com/open-swift http://www.zewo.io/

Slide 51

Slide 51 text

CAESAR WIRTH github.com/cjwirth twitter.com/cjwirth cjwirth.com AKIBA.SWIFT - APRIL 26, 2016