From REST to gRPC:
Joe Runde
IBM
@joerunde
Michael Keeling
IBM
@michaelkeeling
An API Evolution Story
2
What is gRPC?
Open source Remote Procedure Call framework
3
What is gRPC?
Open source Remote Procedure Call framework
4
“… a modern, bandwidth and CPU efficient, low latency way to create massively distributed systems that span data centers”
5
Why should we use gRPC?
Why is gRPC awesome?
6
Performance
Performance Benefits
7
HTTP / REST
Performance Benefits
8
HTTP / REST gRPC
How does gRPC improve performance?
• HTTP/2 transport protocol
• Binary encodings via protocol buffers
• No more parsing text!
• Compression
• Streaming
9
Why is gRPC awesome?
10
Performance
Why is gRPC awesome?
11
Performance
Remote Procedure Calls
REST setup is tedious
12
headers = {}
headers.put(“X-FooBar-User”,
user.getFooBarID())
headers.put(“FooBarTransaction”,
app.getNextTxnIDAtomic())
headers.put(“FooBarAlgoType”,
ApproximateFoo.toHeaderString())
REST setup is tedious
13
Public class Foo {
@JsonProperty(name=”foo_id”)
String id;
@JsonProperty(name=”bar”)
int bar;
...
}
REST setup is tedious
14
Public class Foo {
...
public
Foo(@JsonProperty(“foo_id”,required=true)
String id,
@JsonProperty(“bar”,required=true)
int bar)
{ ... }
}
RPC setup is easy
15
request = FooService.RequestBuilder()
.setId(foo.getId())
.setBar(foo.getBar())...
.build();
response = fooClient.DoFooBar(request);
Why is gRPC Awesome?
16
Performance
Remote Procedure Calls
Why is gRPC Awesome?
17
Performance
Remote Procedure Calls
Strategic Direction of our Platform
18
<insert slick demo here>
19
Just one problem…
Our current microservices
all use REST.
20
21
Business Constraints
22
The Transition Plan
• Phase 1: Design gRPC API
• Phase 2: Run REST and gRPC services
• Phase 3: Transition functional tests
• Phase 4: Remove REST functionality
23
DESIGN THE APIPhase I
24
Designing a gRPC API
gRPC:
rpc AddFoo(Foo)
returns FooID;
rpc GetFoo(FooID)
returns Foo;
25
REST:
POST
/api/foo
GET
/api/foo/{foo_id}
Designing a gRPC API
gRPC:
message Foo {
FooID id = 1;
repeated Bar bars = 2;
}
message FooID {
string val = 1;
}
26
REST:
POST
/api/foo
GET
/api/foo/{foo_id}
Designing a gRPC API
gRPC:
rpc AddBar(Bar)
returns BarID;
rpc GetFoo(BarID)
returns Bar;
27
REST:
POST
/api/foo/{foo_id}/bar
GET
/api/foo/{foo_id}/bar/
{bar_id}
Designing a gRPC API
gRPC:
rpc AddBar(Bar)
returns BarID;
rpc GetFoo(BarID)
returns Bar;
28
REST:
POST
/api/foo/{foo_id}/bar
GET
/api/foo/{foo_id}/bar/
{bar_id}
Designing a gRPC API
gRPC:message Bar{
BarID id = 1;
int baz = 2;
}
message BarID {
FooID foo_id = 1;
string bar_id = 2;
}
29
REST:
POST
/api/foo/{foo_id}/bar
GET
/api/foo/{foo_id}/bar/
{bar_id}
Designing a gRPC API
30
Bar service:
/api/foo/{foo_id}/bar/{bar_id}
Buzz service:
/api/foo/{foo_id}/buzz/{buzz_id}
SERVE REST AND GRPCPhase II
31
Current: REST Only
32
FooBar
Service
REST
Caller
Future: REST and gRPC
33
FooBar
Service
REST
Caller
gRPC
Caller
We need to evolve our API without
damaging basic functionality.
34
Code Package
is allowed to
use
Current: Layers View
35
Rest Service
Business Logic
Datastore Access
Models
Models
36
Code Package
is allowed to
use
Rest
Service
Business Logic
Datastore Access
gRPC
Service
Future: Layers View
Layer Pattern Rocks!
A code review comment:
"What's with the service layer? This just passes its inputs to our business logic functions, it's redundant 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 III
41
Specification by Example
42
43
Specification by Example- REST
Ruby metaprogramming
44
Choice of programming language really paid off
request = Object::const_get(
”FooBar::#{message_name}").decode_json(json)
response = client.method(method_name.to_sym)
.call(request)
45
Specification by Example- gRPC
200+ tests transitioned in 1 week
46
Why did this go so well?
47
• Expressiveness of spec by example
• Flexibility of Ruby
• gRPC can decode JSON
REMOVE REST FUNCTIONALITYPhase 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
Service
Layers Forked – Two Services
53
ModelsBusiness Logic
Datastore Access
gRPC Service
FooBar
Service
gRPC Clients
REST ServiceFooBar
Proxy
Service
Evil wizards strike again!
54
NOW WE’RE READY FOR RELEASE…?
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 use
59
60
Tools support
• Basically Nonexistent
• Our solutions:• Hand roll mocks for testing
• Write new functional tests each time we wanted to use curl
61
62
Adios,
REST!
INTERESTING THINGS WE LEARNED
63
• The right kinds of abstractions promote
extensibility
• Focus on the domain model
• Create a specification by example
• Take care when choosing frameworks
• Deal with risks of technology adoption
64
Would we do it again?
65
Would we do it again?
• Super easy to integrate with a service
• Promotes small polyglot services
• Difficult to do bad things
• Performance is 🔥🔥🔥
66
Yes.
Thank you!
Michael Keeling
@michaelkeeling
neverletdown.net
Joe Runde
@joerunde
Buy Design It! now at
http://bit.ly/2pJOrly
68
BACKUP
69
70
71
72