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

Building practical web application with Slimane

Building practical web application with Slimane

Slide that is used in 2016 May 31 Tokyo server side swift meetup

9ebab3d4f66a62a859ad238e7e97597f?s=128

Yuki Takei

June 01, 2016
Tweet

Transcript

  1. B U I L D I N G P R

    A C T I C A L W E B A P P L I C AT I O N W I T H S L I M A N E 2 0 1 6 M A Y 3 1 T O K Y O S E R V E R S I D E S W I F T M E E T U P Y U K I TA K E I
  2. Hello! I’m Yuki Takei

  3. ChatCast

  4. SmartDrive

  5. ຊ೔ͷൃද͸ɺ్தͰσϞΛ͸͞Έ·͢ɻ ࣗ෼΋खΛಈ͔͠ͳΒσϞΛମݧ͍ͨ͠ͱ͍͏͜ͱ͸ɺ https://github.com/noppoMan/slimane-github-issue-manager Λgit cloneͯ͠vagrant upΛ༧Ί͓͍͍ͯͯͩ͘͠͞ɻ

  6. I have glad news

  7. Finally My PRs are merged to Open-Swift!

  8. None
  9. None
  10. W H AT I S O P E N -

    S W I F T ? • C7: Core standards for Swift (Data, Stream etc…) • S4: HTTP standards for Swift (Request/Response etc..) • D5: Database standards for Swift. Open source cross project standards for Swift.
  11. Anyways

  12. How do you make Web Applications?

  13. With Rails, Node.js, Django and Play etc..?

  14. Today, I propose you to build it with Swift

  15. Building Practical Web Application with Swift? Seriously?

  16. Yes We can!

  17. W H AT S O F T WA R E

    S A R E N E E D E D T O B U I L D I T ? • HTTP Servers • Application Frameworks • Template Engines • Database Clients • Deployment
  18. Slimane Provides all of them!

  19. None
  20. S L I M A N E I S …

    • Express inspired Web Application Framework • 100% asynchronous with event loop backend (libuv) • Standalone HTTP Server • Faster • Moduler • Full managed asynchronous Stream, TCP, Pipe, FileSystem, Process, Timer etc.. • Adopt Open-Swift
  21. Today I show you how to create the Issue Manager

    for Github made with Slimane
  22. S P E C I F I C AT I

    O N • List issues • Get a single issue • Create issues • Post comments • Broadcast the comment to all clients via Web socket
  23. B A C K E N D S T R

    U C T U R E S pub/sub pub/sub reverse proxy app1 app2 github api ɾOS: Ubuntu(Vagrant) ɾCore: 4 ɾRAM: 2048MB
  24. F R O N T E N D • Template

    Engine: Mustache/lodash • JS Framework: jQuery • Css Framework: Bootstrap
  25. Demo https://github.com/noppoMan/slimane-github-issue-manager

  26. ɾvagrant up ɾlaunch single app ɾlogin ɾplay around(list issues, create

    an issue) ɾlaunch cluster app ɾweb socket ɾGraceful restart(Not implemented yet..) Menu
  27. Let's take a closer look the codes!

  28. • Get a Slimane server up • HTML Rendering •

    Deal with Github Api • Authentication • Web socket with Redis pub/sub • Asynchronous flow controll • Cluster/Worker • Graceful Restart(Not implemented yet…) Basic Technical Part of Github Issue Manager
  29. Get a Slimane server up import Slimane import JSON let

    app = Slimane() // access log app.use { req, res, next in print("[pid:\(Process.pid)]\t\(Time())\t\(req.path ?? "/")") next(.Chain(req, res)) } // Responsd to the simple json app.get("/") { req, responder in let json: JSON = ["foo": "bar"] responder { Response(body: JSONSerializer().serialize(json: json)) } } try! app.listen()
  30. HTML Rendering // app.swift import Slimane import MustacheViewEngine import Render

    extension Response { static func render(_ path: String, data: TemplateData = ["foo": "bar"]) -> Response { let render = Render(engine: MustacheViewEngine(templateData: data), path: path) return Response(custom: render) } } let app = Slimane() app.get("/") { req, responder in responder { Response.render("index", data: ["foo": "bar"]) } } try! app.listen() // index.mustache <html> <body> <h1>{{ foo }}</h1> </body> </html>
  31. Deal with Github API Actually, We don’t have any SSL

    implementation yet…
  32. But We have….. libcurl! Deal with Github API

  33. Deal with Github API https://github.com/noppoMan/slimane-github-issue- manager/blob/master/Sources/RestClient.swift

  34. Deal with Github API import Thrush import QWFuture struct CurlContext

    { let writeCallback: ([Byte]) -> () } return Promise<Data> { resolve, reject in let future = QWFuture<Data>(loop: self.loop) { (completion: (() throws -> Data) -> ()) in let handle = curl_easy_init() curlHelperSetOptString(handle, CURLOPT_URL, UnsafeMutablePointer(self.uri.buffer)) curlHelperSetOptBool(handle, CURLOPT_HTTPGET, CURL_TRUE) .................. var data = Data() let writeCallback = { (bytes: [Byte]) in data.append(contentsOf: bytes) } curlHelperSetOptWriteFunc(handle, context) { (buf, size, nMemb, privateData) -> Int in let ctx = UnsafePointer<CurlContext?>(privateData) let segsize = size * nMemb var bytes = [Byte]() for i in stride(from: 0, to: segsize, by: 1) { bytes.append(Byte(bitPattern: buf![i])) } ctx?.pointee?.writeCallback(bytes) return segsize } curl_easy_perform(handle) curl_easy_cleanup(handle) completion { data } } future.onSuccess { resolve($0) } future.onFailure { reject($0) }
  35. libcurl + Future(uv_queue_work) + Promise Deal with Github API

  36. Deal with Github API Usage RestClient( method: .get, uri: "https://api.github.com/repos/noppoMan/Slimane/issues",

    body: JSONSerializer().serialize(json: ["body": data["body"]!.string!]) ) .send() .then { response in if 200..<300 ~= response.statusCode { success() } else { error() } } .failure { error in print(error) }
  37. Authentication https://github.com/noppoMan/slimane-github-issue- manager/blob/master/Sources/ AuthenticationMiddleware.swift

  38. WebSocket with Redis pub/sub https://github.com/noppoMan/slimane-github-issue- manager/blob/master/Sources/ChatRoute.swift

  39. Asynchronous flow controll ɾnoopoman/Thrush ɾslimane-swift/QWFuture

  40. Asynchronous flow controll https://github.com/noppoMan/Thrush - Promise-

  41. Asynchronous flow controll https://github.com/slimane-swift/QWFuture - QWFuture -

  42. Cluster and Worker https://github.com/noppoMan/slimane-github-issue- manager

  43. Thanks!