From REST To GRPC - Carnegie Mellon University

Transcription

From REST to gRPC:An API Evolution StoryJoe RundeIBM@joerundeMichael KeelingIBM@michaelkeeling

2

What is gRPC?Open source Remote Procedure Call framework3

What is gRPC?Open source Remote Procedure Call framework“ a modern, bandwidth and CPU efficient, low latencyway to create massively distributed systems that spandata centers”4

Why should we use gRPC?5

Why is gRPC awesome?Performance6

Performance BenefitsHTTP / REST7

Performance BenefitsHTTP / RESTgRPC8

How does gRPC improve performance? HTTP/2 transport protocol Binary encodings via protocol buffers No more parsing text! Compression Streaming9

Why is gRPC awesome?Performance10

Why is gRPC awesome?PerformanceRemote Procedure Calls11

REST setup is tediousheaders roximateFoo.toHeaderString())12

REST setup is tediousPublic class Foo {@JsonProperty(name ”foo id”)String id;@JsonProperty(name ”bar”)int bar;.}13

REST setup is tediousPublic class Foo {.publicFoo(@JsonProperty(“foo id”,required true)String id,@JsonProperty(“bar”,required true)int bar){ . }}14

RPC setup is easyrequest Bar(foo.getBar()).build();response fooClient.DoFooBar(request);15

Why is gRPC Awesome?PerformanceRemote Procedure Calls16

Why is gRPC Awesome?PerformanceRemote Procedure CallsStrategic Direction of our Platform17

18

insert slick demo here 19

Just one problem Our current microservicesall use REST.20

21

Business Constraints22

The Transition Plan Phase 1: Design gRPC API Phase 2: Run REST and gRPC services Phase 3: Transition functional tests Phase 4: Remove REST functionality23

DESIGN THE APIPhase I24

Designing a gRPC APIREST:gRPC:POST/api/foorpc AddFoo(Foo)returns FooID;GET/api/foo/{foo id}rpc GetFoo(FooID)returns Foo;25

Designing a gRPC APIREST:gRPC:POST/api/foomessage Foo {FooID id 1;repeated Bar bars 2;}GET/api/foo/{foo id}message FooID {string val 1;}26

Designing a gRPC APIREST:gRPC:POST/api/foo/{foo id}/barrpc AddBar(Bar)returns BarID;GET/api/foo/{foo id}/bar/{bar id}rpc GetFoo(BarID)returns Bar;27

Designing a gRPC APIREST:gRPC:POST/api/foo/{foo id}/barrpc AddBar(Bar)returns BarID;GET/api/foo/{foo id}/bar/{bar id}rpc GetFoo(BarID)returns Bar;28

Designing a gRPC APIREST:POST/api/foo/{foo id}/barGET/api/foo/{foo id}/bar/{bar id}gRPC:message Bar{BarID id 1;int baz 2;}message BarID {FooID foo id 1;string bar id 2;}29

Designing a gRPC APIBar service:/api/foo/{foo id}/bar/{bar id}Buzz service:/api/foo/{foo id}/buzz/{buzz id}30

SERVE REST AND GRPCPhase II31

Current: REST OnlyRESTCallerFooBarService32

Future: REST and gRPCRESTCallergRPCCallerFooBarService33

We need to evolve our API withoutdamaging basic functionality.34

Current: Layers ViewRest ServiceCode PackageBusiness Logicis allowed touseModelsDatastore Access35

Future: Layers ViewRestServicegRPCServiceCode PackageBusiness Logicis allowed touseModelsDatastore Access36

Layer Pattern Rocks!A code review comment:"What's with the servicelayer? This just passesits inputs to our businesslogic functions, it'sredundant cruft!"37

Evolving the code went really well 38

39

Things that suddenly became a problem Health Checks API Discovery No curl Headers? SSL? Simple community examples40

TRANSITION FUNCTIONAL TESTSPhase III41

Specification by Example42

Specification by Example- REST43

Ruby metaprogrammingChoice of programming language really paid offrequest Object::const get(”FooBar::#{message name}").decode json(json)response client.method(method name.to sym).call(request)44

Specification by Example- gRPC45

200 tests transitioned in 1 week46

Why did this go so well? Expressiveness of spec by example Flexibility of Ruby gRPC can decode JSON47

REMOVE REST FUNCTIONALITYPhase IV48

rm –rf src/*rest*49

We need to retain some REST endpointsRESTCallergRPCCallerFooBarService50

51

Current Layered ArchitectureServiceRestServicegRPCServiceBusiness LogicModelsFooBarServiceDatastore Access52

Layers Forked – Two ServicesREST ServiceFooBarProxygRPC ClientsServicegRPC ServiceBusiness LogicModelsFooBarServiceDatastore Access53

Evil wizards strike again!54

NOW WE’RE READY FORRELEASE ?55

New problems we created Health Checks API Discovery No curl Headers? SSL?56

New problems we created Health Checks API Discovery No curl Headers? SSL?57

API Discovery REST – Ask the service! gRPC – Find the (correct) proto file?58

API Discovery REST – Ask the service! gRPC – Find the (correct) proto file? Standard InfoService serves github url version Snapshot proto files with releases Client vendors the proto files they use59

60

Tools support Basically Nonexistent Our solutions: Hand roll mocks for testing Write new functional tests each time wewanted to use curl61

Adios,REST!62

INTERESTING THINGS WELEARNED63

The right kinds of abstractions promoteextensibility Focus on the domain model Create a specification by example Take care when choosing frameworks Deal with risks of technology adoption64

Would we do it again?65

Would we do it again?Yes. Super easy to integrate with a service Promotes small polyglot services Difficult to do bad things Performance is 66

Thank you!Michael Keeling@michaelkeelingneverletdown.netJoe Runde@joerundeBuy Design It! now athttp://bit.ly/2pJOrly

BACKUP68

69

70

71

72

Flexibility of Ruby gRPC can decode JSON. REMOVE REST FUNCTIONALITY Phase IV 48. 49 rm -rf src/*rest* We need to retain some REST endpoints 50 REST Caller gRPC Caller FooBar Service. 51. Current Layered Architecture 52 Models Rest Service Business Logic Datastore Access gRPC Service FooBar Service