Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

MCE^3 - Kyle Fuller - End-to-end Building Web Services in-swift-mce-2016

75 views

Published on

With open source Swift, Apple has created a new range of possibilities. You can now take existing knowledge and code and apply then to web application development.

This talk will show you how you can reuse existing skills to build and deploy your first web service in Swift.

Published in: Technology
  • Be the first to comment

  • Be the first to like this

MCE^3 - Kyle Fuller - End-to-end Building Web Services in-swift-mce-2016

  1. 1. End-to-end: Building a Web Service in Swift
  2. 2. Who am I?
  3. 3. How many of you have build web services or APIs?
  4. 4. What is a web service?
  5. 5. Why Swift on Server?
  6. 6. Swift
  7. 7. Why do many use scripting languages for the web?
  8. 8. Code Sharing
  9. 9. Accessible to mobile developers
  10. 10. Performance
  11. 11. Performance Graph Server | Language | request/sec | Comparison ---------|----------|-------------|------------ Curassow | Swift | 7715.83 | Gunicorn | Python | 5269.49 | 32% less req/s than Curassow Unicorn | Ruby | 4253.33 | 45% less req/s Curassow
  12. 12. How
  13. 13. /// Format the given string for presentation func formatForDate(date: NSDate) -> String { let formatter = NSDateFormatter() formatter.formatString = "DD MM yyyy" return formatter.stringForDate(date) }
  14. 14. func viewDidLoad() { super.viewDidLoad() // Using our date formatting in iOS button.title = formatForDate(NSDate()) }
  15. 15. import Frank get { return formatForDate(NSDate()) }
  16. 16. $ swift build $ .build/debug/date-example
  17. 17. $ curl http://localhost:8000/ 21 04 2016
  18. 18. Where to begin
  19. 19. Life-cycle
  20. 20. Planning
  21. 21. https://apiblueprint.org/
  22. 22. # Render [POST /render] + Request (application/json) { "template": "Hello {{ name }}", "context": { "name": "Kyle" } }
  23. 23. # Preview [POST /preview] + Response 200 Hello Kyle
  24. 24. Development
  25. 25. Swift Package Manager
  26. 26. Swift 2 vs Swift 3
  27. 27. swiftenv https://swiftenv.fuller.li/
  28. 28. $ swiftenv install 2.2
  29. 29. $ swiftenv local DEVELOPMENT-SNAPSHOT-2016-02-08-a
  30. 30. $ cat .swift-version DEVELOPMENT-SNAPSHOT-2016-02-08-a
  31. 31. $ swift --version Apple Swift version 2.2 $ cd Stencil $ swift --version Apple Swift version 3.0-dev
  32. 32. Web Frameworks
  33. 33. Separation of Concerns Web Servers / Web Frameworks
  34. 34. Frank
  35. 35. get("users", "kyle", "followers") { request in }
  36. 36. get("users", *) { (request, username: String) in }
  37. 37. Custom Parameter Type enum Status { case Open case Closed }
  38. 38. Custom Parameter Type extension Status : ParameterConvertible { init?(parser: ParameterParser) { switch parser.shift() ?? "" { case "open": self = .Open case "closed": self = .Closed default: return nil } } }
  39. 39. get("issues", *) { (request, status: Status) in return "Issues using status: (status)" }
  40. 40. Swift Safety get("/users/:username") { (request, params) in let username = params["username"]! return "Hello (username)" }
  41. 41. let router = Router() router.get("/users/:username") { request, response, next in let username = request.params["username"] ?? "(nil)" try response.status(HttpStatusCode.OK).send("Hello (username)") } let server = HttpServer.listen(8090, delegate: router) Server.run()
  42. 42. Web Server
  43. 43. Curassow https://curassow.fuller.li/
  44. 44. $ curassow --workers 5 [INFO] Listening at http://localhost:8080 (65416) [INFO] Booting worker process with pid: 65417 [INFO] Booting worker process with pid: 65418 [INFO] Booting worker process with pid: 65419 [INFO] Booting worker process with pid: 65420 [INFO] Booting worker process with pid: 65421
  45. 45. Standards
  46. 46. Learn from others' mistakes
  47. 47. Tight Coupling
  48. 48. Nest https://github.com/nestproject/Nest
  49. 49. func application(request: RequestType) -> ResponseType { return Response(.Ok, body: "Hello World") }
  50. 50. Nest Enhancement Proposals
  51. 51. Template Languages
  52. 52. Stencil http://stencil.fuller.li/
  53. 53. There are {{ articles.count }} articles. {% for article in articles %} - {{ article.title }} by {{ article.author }}. {% endfor %}
  54. 54. <h1>Users</h1> <ul> {% for user in users %} <li>{{ user }}</li> {% endfor %} </ul>
  55. 55. Persistence
  56. 56. ORM Object Relational Mapping
  57. 57. QueryKit http://querykit.org/ let user = User.queryset(context) .filter { $0.name == "Kyle" } .orderBy {} .first
  58. 58. Redis (Redbird) let client = try Redbird(config: ...) // Set name to MCE try client.command("SET", params: ["name", "MCE"]) // Get the name try client.command("GET", params: ["name"])
  59. 59. PostgreSQL let connection = Connection(host: "localhost", databaseName: "db") try connection.open() let usernames = try connection.execute("SELECT username FROM users").map { try $0.data("username") }
  60. 60. Testing
  61. 61. Spectre http://spectre.fuller.li/
  62. 62. describe("a person") { let person = Person(name: "Kyle") $0.it("has a name") { try expect(person.name) == "Kyle" } $0.it("returns the name as description") { try expect(person.description) == "Kyle" } }
  63. 63. XCTest
  64. 64. class PersonTests: XCTestCase { let person = Person(name: "Kyle") func testPersonName() { XCTAssertEqual(person.name, "Kyle") } func testPersonDescription() { XCTAssertEqual(person.description, "Kyle") } }
  65. 65. extension PersonTests: XCTestCaseProvider { var allTests : [(String, () throws -> Void)] { return [ ("testPersonName", testPersonName), ("testPersonDescription", testPersonDescription), ] } } XCTMain([ PersonTests(), ])
  66. 66. Dredd https://github.com/apiaryio/dredd
  67. 67. Swift on Travis CI https://swiftenv.fuller.li/en/latest/ integrations/travis-ci.html
  68. 68. Deployment
  69. 69. https://github.com/kylef/heroku-buildpack-swift
  70. 70. $ cat Package.swift import PackageDescription let package = Package( name: "Hello", dependencies: [ .Package(url: "https://github.com/nestproject/Frank.git", majorVersion: 0, minor: 3), ] )
  71. 71. $ cat Sources/main.swift import Frank get { _ in return "Hello World" } get(*) { (_, username: String) in return "Hello (username)" }
  72. 72. $ cat .swift-version 2.2-SNAPSHOT-2016-01-11-a
  73. 73. $ swift build $ .build/debug/Hello [INFO] Listening at http://0.0.0.0:8000 (48827) [INFO] Booting worker process with pid: 48828
  74. 74. $ cat Procfile web: Hello
  75. 75. $ heroku create --buildpack https://github.com/kylef/heroku-buildpack-swift.git $ git push heroku master remote: -----> Swift app detected remote: -----> Installing 2.2-SNAPSHOT-2016-01-11-a remote: -----> Installing clang-3.7.0 remote: -----> Building Package remote: -----> Copying binaries to 'bin'
  76. 76. Manual Deployment
  77. 77. Monitoring
  78. 78. Logging
  79. 79. print("ERROR: Connection to database failed (error)")
  80. 80. Papertrail
  81. 81. What's Next?
  82. 82. Swift 3
  83. 83. Stability
  84. 84. Maturity
  85. 85. What have we covered today • Why you might want to build a web application in Swift • How you can design, develop, deploy Swift web applications
  86. 86. kylefuller https://fuller.li/talks

×