|
10 | 10 | - [Protocol](#protocol)
|
11 | 11 | - [Server](#server)
|
12 | 12 | - [Client](#client)
|
| 13 | +- [Evolving the Avro schema](#evolving-the-avro-schema) |
| 14 | + - [Protocol](#protocol-1) |
13 | 15 |
|
14 | 16 | <!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
15 | 17 |
|
@@ -290,6 +292,67 @@ for {
|
290 | 292 | } yield exitCode
|
291 | 293 | ```
|
292 | 294 |
|
| 295 | +## Evolving the Avro schema |
| 296 | + |
| 297 | +As we have seen before, both client and server are using the same common protocol defined via Avro schema, which is an ideal scenario but realistically speaking the server side might need to add certainly changes in the model. Then how the server can preserve the compatibility with clients that are still using the old model? |
| 298 | + |
| 299 | +Thanks to the Avro definitions we can add evolutions to the models in a safety way, keeping all the clients fully compatible but obviously, there are some limited operations that can't be done, like removing a field in a response model or adding a new required field to a request object. |
| 300 | + |
| 301 | +To illustrate that non-updated clients are able to keep interacting with evolved servers, we'll just add a new field `phone` to `Person`. |
| 302 | + |
| 303 | +### Protocol |
| 304 | + |
| 305 | +Let's add a new evolution to the models described in the protocol |
| 306 | + |
| 307 | +**_People.avdl_** |
| 308 | + |
| 309 | + |
| 310 | +```scala |
| 311 | +protocol People { |
| 312 | + |
| 313 | + record Person { |
| 314 | + string name; |
| 315 | + int age; |
| 316 | + string phone; |
| 317 | + } |
| 318 | + |
| 319 | + record PeopleRequest { |
| 320 | + string name; |
| 321 | + } |
| 322 | + |
| 323 | + record PeopleResponse { |
| 324 | + Person person; |
| 325 | + } |
| 326 | + |
| 327 | +} |
| 328 | +``` |
| 329 | + |
| 330 | +We can now run the server app using this new version, and the client app with the previous one, and the requests should have been processed properly on both sides. |
| 331 | + |
| 332 | +As we can see, the client digests `Person`s instances included in the responses as expected: |
| 333 | + |
| 334 | +```scala |
| 335 | +INFO - Created new RPC client for (localhost,19683) |
| 336 | +INFO - Request: foo |
| 337 | +INFO - Result: PeopleResponse(Person(foo,24)) |
| 338 | +INFO - Request: bar |
| 339 | +INFO - Result: PeopleResponse(Person(bar,9)) |
| 340 | +INFO - Request: baz |
| 341 | +INFO - Result: PeopleResponse(Person(baz,17)) |
| 342 | +INFO - Removed 1 RPC clients from cache. |
| 343 | +``` |
| 344 | + |
| 345 | +Even when actually the server is including the telephone numbers at them: |
| 346 | + |
| 347 | +```scala |
| 348 | +INFO - PeopleService - Request: PeopleRequest(foo) |
| 349 | +INFO - PeopleService - Sending response: Person(foo,24,(206) 198-8396) |
| 350 | +INFO - PeopleService - Request: PeopleRequest(bar) |
| 351 | +INFO - PeopleService - Sending response: Person(bar,9,(206) 740-2096) |
| 352 | +INFO - PeopleService - Request: PeopleRequest(baz) |
| 353 | +INFO - PeopleService - Sending response: Person(baz,17,(206) 812-1984) |
| 354 | +``` |
| 355 | + |
293 | 356 | <!-- DOCTOC SKIP -->
|
294 | 357 | # Copyright
|
295 | 358 |
|
|
0 commit comments