Guest User

Untitled

a guest
Mar 22nd, 2018
80
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.95 KB | None | 0 0
  1. # Scenario
  2.  
  3. A spec model:
  4. ```
  5. "models":{
  6. "my_model": {
  7. "fields":[
  8. {"name": "a", "type": "int"}
  9. ]
  10. }
  11. }
  12. ```
  13.  
  14. has previously generated code
  15.  
  16. `case class MyModel (a: Integer)`
  17.  
  18. We want to introduce a new field to our spec with minimal impact, including avoiding the impact of handling optionality/nullility to the degree possible.
  19.  
  20. ```"models":{
  21. "my_model": {
  22. "fields":[
  23. {"name": "a", "type": "int"},
  24. {"name": "b", "type": "string", "default": "none"},
  25. ]
  26. }
  27. }```
  28.  
  29. generates code
  30.  
  31. ```case class MyModel (
  32. a: Integer,
  33. b: String
  34. )
  35. ...
  36. implicit def jsonReadsMyModel: play.api.libs.json.Reads[MyModel] = {
  37. (
  38. (__ \ "a").read[Integer] and
  39. (__ \ "b").read[String]
  40. )(MyModel.apply _)
  41. }
  42. ```
  43.  
  44. along with client code that may look something like
  45.  
  46. ```
  47. project io.example.clients
  48.  
  49. case class MyModelForm(
  50. a: Integer,
  51. b: String = "none"
  52. )
  53. case object myModels{
  54. def put(myModel: MyModelForm): Unit
  55. }
  56. ```
  57.  
  58. ## No problem
  59.  
  60. A consumer of the API using a current or prior client to GET /my-model will receive the expected model.
  61. A consumer of the API using Postman, etc will receive the content they expect, plus an extra field b.
  62. A consumer of the API using the latest generated client to PUT to /my-model may omit b. The client will fill in the default value.
  63.  
  64. ## Problem
  65.  
  66. A consumer of the API using a prior model of client to PUT to /my-model finds that their client no longer works, as the client is not aware of the default.
  67. A consumer of the API using Postman etc to PUT to /my-model finds that old Requests no longer work.
  68. Models that were written (to a database, s3 etc) using a previous version of the spec will no longer be valid for the new spec. These will need to be updated without using generated tools.
  69.  
  70. # Proposed Solution
  71.  
  72. For older clients and existing models to support the new fields without rework, in the Scala generator we introduce application of the default to
  73. the model's unmarshalling implementation.
  74.  
  75.  
  76. ```implicit def jsonReadsMyModel: play.api.libs.json.Reads[MyModel] = {
  77. (
  78. (__ \ "a").read[Integer] and
  79. (__ \ "b").readWithDefault[String]("none")
  80. )(MyModel.apply _)
  81. }
  82. ```
  83.  
  84. ## Unchanged
  85.  
  86. A consumer of the API using a current or prior client to GET /my-model will receive the expected model.
  87. A consumer of the API using Postman, etc will receive the content they expect, plus an extra field b.
  88. A consumer of the API using the latest generated client to PUT to /my-model may omit b. The client will fill in the default value.
  89.  
  90. ## Changed
  91.  
  92. A consumer of the API using a prior model of client to PUT to /my-model finds that their client still works. The server introduces the default value when unmarshalling the request.
  93. A consumer of the API using Postman etc to PUT to /my-model finds that old Requests no longer work. The server introduces the default value when unmarshalling the request.
  94. Models that were written (to a database, s3 etc) using a previous version of the spec remain valid. Defaults will be introduced on unmarshalling.
Add Comment
Please, Sign In to add comment