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

Otemachi.swift x Kyobashi.swift #02: Vapor + ProtocolBuffers + DockerでServer Side Swift入門

Otemachi.swift x Kyobashi.swift #02: Vapor + ProtocolBuffers + DockerでServer Side Swift入門

Takeshi Ihara

January 29, 2018
Tweet

More Decks by Takeshi Ihara

Other Decks in Programming

Transcript

  1. Vapor + ProtocolBuffers +
    DockerͰServer Side Swiftೖ໳
    @nonchalant0303
    Otemachi.swift x Kyobashi.swift #2

    View full-size slide

  2. ࣗݾ঺հ
    • Takeshi Ihara
    • Recruit Marketing Partners
    • iOS Engineer
    • Twitter: @nonchalant0303
    • GitHub: Nonchalant

    View full-size slide

  3. Kyobashi.swift

    View full-size slide

  4. Sample Project
    • https://github.com/Nonchalant/
    VaporProtobufSample
    • Server, Clientͷαϯϓϧίʔυ (GET, POST)
    • Vapor + ProtocolBuffers + Docker

    View full-size slide

  5. Server Side Swift
    https://swift.org/download
    • Swift͕2015೥12݄ʹΦʔϓϯιʔεԽ
    • LinuxαϙʔτΛ։࢝
    • Vapor, Kitura, PerfectͳͲͷϑϨʔϜϫʔΫ͕
    ొ৔

    View full-size slide

  6. Vapor
    https://github.com/vapor/vapor
    • ࠷΋࢖ΘΕ͍ͯΔSwift੡ͷWebϑϨʔϜϫʔ
    Ϋ
    • PHPͷLaravelϑϨʔϜϫʔΫʹӨڹΛड͚ͯ
    ͍Δ
    • Swift Package ManagerʹΑΔϥΠϒϥϦ؅ཧ
    • पลπʔϧ΋ॆ࣮

    View full-size slide

  7. Vapor / Toolbox
    https://github.com/vapor/toolbox
    • ެ͕ࣜఏڙ͍ͯ͠ΔCLλεΫπʔϧ

    CSFXJOTUBMMWBQPSUBQUPPMCPY
    WBQPSOFX\QSPKFDU@OBNF^ŠBQJ
    WBQPSCVJME
    WBQPSSVO

    View full-size slide

  8. Environment
    WBQPSŠWFSTJPO
    7BQPS5PPMCPY
    7BQPS'SBNFXPSL
    TXJGUŠWFSTJPO
    "QQMF4XJGUWFSTJPO TXJGUMBOH
    DMBOH

    5BSHFUY@BQQMFNBDPTY
    TXJGUQBDLBHFUPPMTWFSTJPO

    View full-size slide

  9. Droplet.swift
    https://github.com/vapor/vapor/blob/master/Sources/Vapor/Droplet/Droplet.swift
    • VaporͷRoutingΛ࢘ΔΫϥε
    extension Droplet {
    func setupRoutes() throws {
    get("hello") { req in
    var json = JSON()
    try json.set("hello", "world")
    return json
    }
    }
    }
    ฦΓ஋͕"1*Ϩεϙϯε

    View full-size slide

  10. ProtocolBuffers (protobuf)
    https://github.com/google/protobuf
    • Google͕։ൃͨ͠௨৴΍ӬଓԽͰͷར༻Λ

    ໨తͱͨ͠γϦΞϥΠζϑΥʔϚοτ
    • .protoͰσʔλߏ଄Λఆٛ͢Δ
    • Apple͕.swiftʹม׵͢ΔϓϥάΠϯΛެ։

    View full-size slide

  11. protobufͷϝϦοτ
    • σʔλྔ͕খ͍͞
    • ௨৴ͷߴ଎Խ
    • σʔλߏ଄Λෳ਺ϓϥοτϑΥʔϜͰڞ༗Մೳ

    View full-size slide

  12. protobuf - ಋೖ
    https://github.com/apple/swift-protobuf
    CSFXJOTUBMMQSPUPCVG
    HJUDMPOFHJU!HJUIVCDPNBQQMFTXJGUQSPUPCVGHJU
    DETXJGUQSPUPCVGTXJGUCVJME
    HFOFSBUFCVJMEEFCVHQSPUPDHFOTXJGU

    View full-size slide

  13. .proto
    syntax = "proto3";
    import "proto/gender.proto";
    message User {
    int64 id = 1;
    string name = 2;
    Gender gender = 3;
    }

    View full-size slide

  14. generate .swift
    QSPUPDŠQMVHJOQSPUPDHFOTXJGUCVJMEEFCVH
    QSPUPDHFOTXJGUŠTXJGU@PVU6TFSQSPUP

    View full-size slide

  15. User.pb.swift
    import Foundation
    import SwiftProtobuf

    struct User: SwiftProtobuf.Message {
    static let protoMessageName: String = "User"
    var id: Int64 = 0
    var name: String = String()
    var gender: Gender = .other
    var unknownFields = SwiftProtobuf.UnknownStorage()
    init() {}

    }

    View full-size slide

  16. Serialize
    extension Message {

    public func serializedData(partial: Bool = default) throws -> Data
    public func jsonUTF8Data() throws -> Data

    }

    View full-size slide

  17. Vapor + protobuf
    extension Droplet {
    func setupRoutes() throws {
    get("user") { req in
    return UserResponse.with {
    $0.users = [
    User.with {
    $0.name = "Takeshi Ihara"
    $0.gender = Gender.male
    },
    User.with {
    $0.name = "Hanako Yamada"
    $0.gender = Gender.female
    }
    ]
    }.serializedData() // or .jsonUTF8Data()
    }
    }
    }

    View full-size slide

  18. Deserialize (Client)
    var urlRequest = URLRequest(url: URL(string: "http://localhost:
    9000/user")!)
    urlRequest.allHTTPHeaderFields = [
    "Accept": "application/protobuf"
    ]
    URLSession.shared.dataTask(with: urlRequest) { data, _, _ in
    guard let data = data else {
    return
    }
    let response = try! UserResponse(serializedData: data)
    }.resume()
    • Serverͱಉ͡ϞσϧΛ࢖͑Δ (User.pb.swift)

    View full-size slide

  19. Docker
    https://www.docker.com/
    • ίϯςφܕͷԾ૝Խ؀ڥΛఏڙ͢ΔΦʔϓϯιʔ
    ειϑτ΢ΣΞ
    • ׬શԾ૝ԽͰ͸ͳ͘1ϓϩηε
    • VMWareͳͲͷ׬શԾ૝Խʹൺ΂ͯɺσΟεΫ
    ࢖༻ྔ͕গͳ͍ɺىಈ͕ૣ͍ɺॲཧ͕ߴ଎

    View full-size slide

  20. docker-swift
    https://github.com/swiftdocker/docker-swift
    • UbuntuͰಈ࡞ՄೳͳApple͕ఏڙ͍ͯ͠ΔSwift
    όΠφϦ͕ಈ࡞ՄೳͳDockerΠϝʔδ
    • ຊ൪ʹ͍ۙLinuxͰͷಈ࡞ΛݕূͰ͖Δ
    • FoundationͳͲͷίΞϥΠϒϥϦ͸MacOS, Linux
    ͷίʔυ͕ҟͳΔ (Linux൛͸ෆ׬શ)

    View full-size slide

  21. Dockerfile
    FROM swift:4.0.3
    USER root
    RUN mkdir -p /server
    COPY ./Config /server/Config
    COPY ./Sources /server/Sources
    COPY ./Makefile /server/Makefile
    COPY ./Package.resolved /server/Package.resolved
    COPY ./Package.swift /server/Package.swift
    ENV PORT 9000
    EXPOSE 9000
    WORKDIR /server
    RUN make build
    CMD ["make", "run"]

    View full-size slide

  22. docker-compose
    https://docs.docker.com/compose/
    • ෳ਺ίϯςφͷఆٛɾىಈͷߏ੒πʔϧ
    version: "2"
    services:
    server:
    image: nonchalant/server:0.1
    ports:
    - "9000:9000"
    ϩʔΧϧɺԾ૝؀ڥͷϙʔτͷϚοϐϯά

    View full-size slide

  23. ·ͱΊ
    • ؆୯ͳπʔϧɾΞϓϦͳͲ͸Server Side SwiftͰ
    ॻ͍ͯ΋͍͍͔΋
    • Linux - SwiftίΞϥΠϒϥϦ͕ະ׬੒ͳͷ͕πϥ
    Π (࣮ߦ࣌Τϥʔ)
    • Clientͷಈ࡞ݕূʹ΋Docker࢖͑Δ͔΋
    (CircleCI 2.0)

    View full-size slide