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

Envoy Mobile & the upcoming networking revolution

Sponsored · SiteGround - Reliable hosting with speed, security, and support you can count on.

Envoy Mobile & the upcoming networking revolution

Talk given at Swiftable in Buenos Aires, Argentina in November 2019.

Avatar for Michael Rebello

Michael Rebello

November 29, 2019

Other Decks in Programming

Transcript

  1. let params: [String: Any] = [ "lat": position.latitude, "lng": position.longitude,

    "some_param": true, ] client.request(.post, "/foo", parameters: params) { result in … } Early APIs at Lyft
  2. import Mapper extension FooResponse: Mappable { init(map: Mapper) throws {

    self.placeID = try map.from("place_id") let item: String? = map.optionalFrom("items") self.placeDisplay = map.optionalFrom("display.lien_two") } } Deserialization failures
  3. import Mapper extension FooResponse: Mappable { init(map: Mapper) throws {

    self.placeID = try map.from("place_id") let item: String? = map.optionalFrom("items") self.placeDisplay = map.optionalFrom("display.lien_two") } } Deserialization failures
  4. import Mapper extension FooResponse: Mappable { init(map: Mapper) throws {

    self.placeID = try map.from("place_id") let item: String? = map.optionalFrom("items") self.placeDisplay = map.optionalFrom("display.lien_two") } } Deserialization failures
  5. • Handwritten code led to mistakes/typos • No visibility into

    deserialization failures • No single source of truth Problems
  6. paths: /foo: post: parameters: - in: body schema: $ref: '#/definitions/FooRequest'

    responses: 200: schema: $ref: '#/definitions/FooResponse' YAML definitions
  7. • Manual code generation for Android • No integration on

    iOS or services • Still inconsistencies across platforms • No single source of truth YAML results
  8. • Simple to write • Open-source generators available for most

    popular languages • JSON support • Optimized wire encoding Why protobuf?
  9. message FooRequest { … } message FooResponse { int64 id

    = 1; string first_name = 2; } service Foo { rpc UpdateFoo(FooRequest) returns (FooResponse) { option (http.http_options).path = "/foo"; option (http.http_options).method = "POST"; } } Protobuf definition
  10. message FooRequest { … } message FooResponse { int64 id

    = 1; string first_name = 2; } service Foo { rpc UpdateFoo(FooRequest) returns (FooResponse) { option (http.http_options).path = "/foo"; option (http.http_options).method = "POST"; } } Protobuf messages
  11. message FooRequest { … } message FooResponse { int64 id

    = 1; string first_name = 2; } service Foo { rpc UpdateFoo(FooRequest) returns (FooResponse) { option (http.http_options).path = "/foo"; option (http.http_options).method = "POST"; } } Protobuf fields
  12. message FooRequest { … } message FooResponse { int64 id

    = 1; string first_name = 2; } service Foo { rpc UpdateFoo(FooRequest) returns (FooResponse) { option (http.http_options).path = "/foo"; option (http.http_options).method = "POST"; } } Protobuf services
  13. message FooRequest { … } message FooResponse { int64 id

    = 1; string first_name = 2; } service Foo { rpc UpdateFoo(FooRequest) returns (FooResponse) { option (http.http_options).path = "/foo"; option (http.http_options).method = "POST"; } } Protobuf RPCs (Remote Procedure Calls)
  14. message FooRequest { … } message FooResponse { int64 id

    = 1; string first_name = 2; } service Foo { rpc UpdateFoo(FooRequest) returns (FooResponse) { option (http.http_options).path = "/foo"; option (http.http_options).method = "POST"; } } Protobuf annotations
  15. // Modules/FooV1API/FooAPI.swift public struct FooRequest: Codable, Equatable { … }

    public struct FooResponse: Codable, Equatable { public let id: Int64 public let firstName: String } Generated models
  16. // Modules/FooV1API/FooAPI.swift import RxSwift public protocol FooAPI { func updateFoo(_

    request: FooRequest) -> Single<Result<FooResponse, FooAPIError>> } public struct FooClientAPI: FooAPI { // Abstracted implementation } Generated APIs
  17. // Modules/FooV1API/FooAPI.swift import RxSwift public protocol FooAPI { func updateFoo(_

    request: FooRequest) -> Single<Result<FooResponse, FooAPIError>> } public struct FooClientAPI: FooAPI { // Abstracted implementation } Generated APIs
  18. // Modules/FooV1APIMock/FooAPI.swift open class FooMockAPI: FooAPI { open lazy var

    mockUpdateFoo: (FooRequest) -> Result<FooResponse, FooAPIError> = { … } open func updateFoo(_ request: FooRequest) -> Single<Result<FooResponse, FooAPIError>> { … } } Generated mocks
  19. // Modules/FooFeatureModule/FooFeature.swift getFooClientAPI() .updateFoo(FooRequest(...)) .subscribe({ result in switch result {

    case .success(let response): // Consume the response case .failure(let error): // Handle the failure } }) .disposed(by: self.disposeBag) Using APIs
  20. ★ Single source of truth for all APIs ★ Consistent

    interfaces across platforms ★ Ergonomic generated code on all platforms ★ Highly testable ★ Wire format fully abstracted Results
  21. Client Service JSON request Content-Type: json Accept: x-protobuf,json Content negotiation

    Middleware (service) JSON > Protobuf Protobuf request Content-Type: x-protobuf Protobuf response Content-Type: x-protobuf Middleware (service) No change Protobuf response Content-Type: x-protobuf
  22. • 40%+ reduction in payload sizes • Faster response times

    • Higher success rates • Transparent to engineers Wins from protobuf
  23. What if we want to change how we send data

    rather than what we send?
  24. Envoy service mesh Service A Proxy Service B Proxy HTTP/1.1,

    HTTP/2, gRPC, etc. HTTP/1.1, HTTP/2, gRPC, etc.
  25. Envoy filters Service A Filter Add auth headers Filter gzip

    request Proxy Proxy Filter Unzip payload Filter Validate auth headers Service B
  26. Envoy service mesh + front proxy Service A Proxy Service

    B Proxy HTTP/1.1, HTTP/2, gRPC, etc. Client Proxy
  27. • 1 network stack for all platforms • Write filter

    functionality once, deploy everywhere • Support new protocols like HTTP/3 (QUIC) • Consistent stats/monitoring across all platforms Envoy Mobile!