type-safe web apis with protocol buffers in swift

Post on 11-Apr-2017

488 Views

Category:

Technology

2 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Type-safe Web APIs with Protocol Buffers in Swift

1 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

Hi, I'm Yusuke@kitasuke

2 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

I'm going to talk about...→ What Protocol Buffers are

3 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

I'm going to talk about...→ What Protocol Buffers are

→ Pros and Cons

4 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

I'm going to talk about...→ What Protocol Buffers are

→ Pros and Cons→ Where to start

5 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

Web APIs6 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

JSON7 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

HTTP RequestJSON ➡ Data

8 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

let json = ["id": 1]let data = try? JSONSerialization.data(withJSONObject: json, options: .prettyPrinted)

var request = URLRequest(url: url)request.httpBody = data

9 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

HTTP ResponseData ➡ JSON

10 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

// {"user": {"name": "Yusuke"}}URLSession.shared.dataTask(with: request) { (data, _, _) in let json = (try? JSONSerialization.jsonObject(with: data!, options: .allowFragments)) as? [AnyHashable: Any] let user = json?["user"] as? [AnyHashable: Any] let name = user?["name"] as? String}

11 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

{"isTyped": false, "status": "disappointed"}

12 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

[AnyHashable: Any]

13 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

Any?

14 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

!

15 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

ProtocolBuffers

a.k.a protobuf16 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

Protocol buffers are Google's language-neutral, platform-neutral, extensible mechanism for

serializing structured data – think XML, but smaller, faster, and simpler.

— Google

17 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

Serialization format- think JSON, but

smaller, faster and safer— Yusuke

18 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

Serialization Format

19 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

Why are Protocol Buffers a big deal?

20 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

HTTP RequestJSON ➡ Data

21 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

let json = ["id": 1]let data = try? JSONSerialization.data(withJSONObject: json, options: .prettyPrinted)

var request = URLRequest(url: url)request.httpBody = data

22 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

HTTP RequestJSON ➡ Data

23 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

HTTP RequestUserRequest ➡ Data

24 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

// custom typelet userRequest = UserRequest.with { $0.id = 1}let body = try? body.serializedData()

var request = URLRequest(url: url)request.httpBody = body

25 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

HTTP ResponseData ➡ JSON

26 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

// {"user": {"name": "Yusuke"}}URLSession.shared.dataTask(with: request) { (data, _, _) in let json = (try? JSONSerialization.jsonObject(with: data!, options: .allowFragments)) as? [AnyHashable: Any] let user = json?["user"] as? [AnyHashable: Any] let name = user?["name"] as? String}

27 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

HTTP ResponseData ➡ JSON

28 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

HTTP ResponseData ➡ UserResponse

29 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

// UserResponse(user: User(name: "Yusuke"))URLSession.shared.dataTask(with: request) { (data, _, _) in // custom type guard let response: UserResponse = try? UserResponse(serializedData: data!) else { // error return } let user = response.user let name = user.name}

30 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

Protobuf( isTyped: true, status: .satisfied)

31 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

!

32 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

But how do they work?

33 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

protobuf for Swiftapple/swift-protobuf

34 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

"But we still use Objective-C !"

35 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

protobufgoogle/protobuf

36 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

1. Define message types2. Generate code

3. Serialize/Deserialize

37 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

1. Define message types2. Generate code

3. Serialize/Deserialize

38 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

Message types define data structures

in .proto files

39 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

Message types have key-value pairs

40 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

41 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

user.proto

syntax = "proto3"; // protoc version

message User { int32 id = 1; // field number string name = 2; string introduction = 3; string photoUrl = 4; ParticipantType participantType = 5;

enum ParticipantType { Speaker = 0; Attendee = 1; }}

42 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

talk.proto

syntax = "proto3";

import "user.proto";

message Talk { int32 id = 1; string title = 2; string desc = 3; User speaker = 4; repeated string tags = 5; // Array}

43 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

1. Define message types2. Generate code

3. Serialize/Deserialize

44 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

protobuf compiler generates code from .proto file

45 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

Basic typesInt32, UInt32, Int64, UInt64, Bool, Float, Double, String,

Array, Dictionary, Data

46 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

Supported languagesC, C++, C#, Erlang, Go, Haskell, Java, Javascript, Objective-C, Perl, PHP, Python, Ruby, Rust, Scala,

Swift etc.

47 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

Swift features→ struct, not class

→ enum RawValue is Int→ Default value is set

48 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

49 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

user.protosyntax = "proto3"; // protoc version

message User { int32 id = 1; // field number string name = 2; string introduction = 3; string photoUrl = 4; ParticipantType participantType = 5;

enum ParticipantType { Speaker = 0; Attendee = 1; }}

50 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

user.pb.swift// structstruct User: SwiftProtobuf.Message, ... { init() {}

enum Type: SwiftProtobuf.Enum { typealias RawValue = Int // always Int case speaker // = 0 case participant // = 1 case UNRECOGNIZED(Int) }

// property has default value var id: Int32 = 0 var name: String = "" var introduction: String = "" var photoURL: String = "" var participantType: User.ParticipantType = .speaker}

51 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

talk.proto

syntax = "proto3";

import "user.proto";

message Talk { int32 id = 1; string title = 2; string desc = 3; User speaker = 4; repeated string tags = 5; // Array}

52 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

talk.pb.swift

struct Talk: SwiftProtobuf.Message, ... { init() {}

var id: Int32 = 0 var title: String = "" var speaker: User = User() var desc: String = "" var tags: [String] = []}

53 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

54 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

User.javapublic static final class User extends Message<User, User.Builder> { public final Integer id; public final String name; public final String introduction; public final String photoUrl; public final ParticipantType participantType;}

55 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

Talk.java

public final class Talk extends Message<Talk, Talk.Builder> { public final Integer id; public final String title; public final User speaker; public final String summary; public final List<String> tags;}

56 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

57 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

user.pb.gotype User_Type int32

const ( User_Speaker User_ParticipantType = 0 User_Attendee User_ParticipantType = 1)

type User struct { ID int32 ˆprotobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"ˆ Name string ˆprotobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"ˆ Introduction string ˆprotobuf:"bytes,3,opt,name=introduction,proto3" json:"introduction,omitempty"ˆ PhotoURL string ˆprotobuf:"bytes,4,opt,name=photoUrl,proto3" json:"photoUrl,omitempty"ˆ Type User_Type ˆprotobuf:"varint,5,opt,name=type,proto3,enum=api.User_Type" json:"type,omitempty"ˆ}

58 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

talk.pb.gotype Talk struct { ID int32 ˆprotobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"ˆ Title string ˆprotobuf:"bytes,2,opt,name=title,proto3" json:"title,omitempty"ˆ Speaker *User ˆprotobuf:"bytes,3,opt,name=speaker" json:"speaker,omitempty"ˆ Summary string ˆprotobuf:"bytes,4,opt,name=summary,proto3" json:"summary,omitempty"ˆ Tags []string ˆprotobuf:"bytes,5,rep,name=tags" json:"tags,omitempty"ˆ}

59 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

One message type⬇

Multiple languages code60 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

Less communication, More collaboration

with other platforms

61 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

1. Define message types2. Generate source files3. Serialize/Deserialize

62 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

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

public func jsonString() throws -> String

public func textFormatString() throws -> String

63 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

let user = User.with { $0.id = 1 $0.type = .speaker $0.name = "kitasuke"}

let talk = Talk.with { $0.id = 1 $0.title = "Type-safe Web APIs with Protocol Buffers in Swift" $0.speaker = user $0.tags = ["swift", "iOS", "protocol-buffers", "ioscon", "type-safe"]}

let data = try? talk.serializedData()

64 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

Deserializationpublic convenience init(serializedData data: Data, extensions: SwiftProtobuf.ExtensionSet? = default, partial: Bool = default) throws

public convenience init(jsonString: String) throws

public convenience init(textFormatString: String, extensions: SwiftProtobuf.ExtensionSet? = default) throws

65 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

let talk = try? Talk(serializedData: data)

let title = talk?.titlelet speaker = talk?.speakerlet tags = talk?.tags

66 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

How serialization works

67 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

Binary Encoding

68 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

Key factor1. Field number

2. Wire type

69 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

Field numbermessage Talk { int32 id = 1; ← // Field number string title = 2; string desc = 3; User speaker = 4; repeated string tags = 5;}

70 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

Wire typeType Meaning Used For0 Varint int32, int64, uint32, uint64,

sint32, sint64, bool, enum1 64-bit fixed64, sfixed64, double2 Length-delimited string, bytes, embedded

messages, packed repeated fields

3 (deprecated)4 (deprecated)5 32-bit fixed32, sfix3d32, float

71 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

// message typemessage Test1 { int32 a = 1;}test1.a = 300

// encoded message08 96 01

08 // field number and wire type96 01 // value which is 300

72 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

So small and numeric

73 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

High network performance

74 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

Demokitasuke/SwiftProtobufSample

75 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

Quick Recap76 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

Quick Recap→ Type-safety

77 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

Quick Recap→ Type-safety

→ Shared data model

78 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

Quick Recap→ Type-safety

→ Shared data model→ High performance

79 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

You might have concerns about...

80 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

Versioning81 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

Backward compatibility→ Unknown field is ignored

→ Default value for missing field

82 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

Backward compatibility→ Unknown field is ignored

→ Default value for missing field

as long as you don't change existing field number or wire type

83 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

Coexistence ofprotobuf & JSON

84 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

Absolutely you can!

85 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

Accept & Content-Type

→ application/protobuf - protobuf→ application/json - JSON

86 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

HTTP Requestvar request = URLRequest(url: url)if protobuf { request.setValue("application/protobuf", forHTTPHeaderField: "Content-Type") request.setValue("application/protobuf", forHTTPHeaderField: "Accept")} else if json { request.setValue("application/json", forHTTPHeaderField: "Content-Type") request.setValue("application/json", forHTTPHeaderField: "Accept")}

87 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

HTTP ResponseURLSession.shared.dataTask(with: request) { (data, urlResponse, _) in let httpURLResponse = urlResponse as? HTTPURLResponse let contentType = httpURLResponse?.allHeaderFields["Content-Type"] as? String

if contentType == "application/protobuf" { let response = try? Response(serializedData: data!) } else if contentType == "application/json" { let response = try? Response(jsonString: data!) }}

88 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

Sounds goodso far !

89 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

So, what are Cons?

90 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

Not human-readable→ Binary data is not understandable

91 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

Time investment→ Time consuming at the beginning→ Involvement from other platforms

92 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

Swift version→ Watch Swift version of protobuf plugin

→ Specify tag version if you use older version

93 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

Stability→ Still pre-release version only for Swift ⚠

→ Contribute if you find a bug !

94 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

Where should we start?

95 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

Internal service

→ Easy to adapt→ Small start

96 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

Data store

→ Database→ NSKeyedArchiver

→ NSCache

97 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

Parsing library

→ JSON parser→ Server side Swift

98 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

Conclusion99 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

Conclusion→ Swifty

100 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

Conclusion→ Swifty

→ Consistent in Cross-platform

101 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

Conclusion→ Swifty

→ Consistent in Cross-platform→ Extensible

102 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

It's definitely worth it !

103 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

Partially in Production70M Downloads

!"#

104 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

CreditsProtocol Buffersswift-protobuf

KituraProtocol Buffers in your Kitura Apps

105 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

Thank you!GitHub: https://github.com/kitasuke

Demo: SwiftProtobufSampleTwitter: @kitasuke

Email: yusuke2759@gmail.com

106 — Type-safe Web APIs with Protocol Buffers in Swift, Yusuke Kita (@kitasuke), iOSCon 2017

top related