You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
=== Type Safety with flexible JSON <- -> POJO marshalling/serialization and unmarshalling/deserialization
379
379
380
-
* ReṼoman internally uses a modern JSON library called https://github.com/square/moshi[**Moshi**]
381
-
* There may be a POJO that inherits or contains legacy types that are hard or impossible to serialize. ReṼoman lets you serialize only types that matter, through `globalSkipTypes`, where you can filter out these legacy types from Marshalling/Unmarshalling
382
-
* The JSON structure may not align with the POJO, and you may need a _Custom Type Adapter_ for Marshalling/Unmarshalling. Moshi has it covered for you with its advanced adapter mechanism and ReṼoman accepts Moshi adapters via:
383
-
** `requestConfig` — For types present as part of request payload for qualified Steps
384
-
** `responseConfig` — For types present as part of response payload for qualified Steps. You can configure separate adapters for success and error response. Use bundled static factory methods like `unmarshallSuccessResponse()` and `unmarshallErrorResponse()` for expressiveness.
380
+
Postman operates purely with JSON.
381
+
When interoperating Postman with JVM,
382
+
unmarshalling/deserialization of JSON into a POJO and vice versa helps in writing Type-safe JVM code and enhances the debugging experience on JVM.
383
+
ReṼoman internally uses a modern JSON library called https://github.com/square/moshi[**Moshi**].
384
+
Simple types whose JSON structure aligns with the POJO data structure can directly be converted.
385
+
But when the JSON structure may not align with the POJO,
386
+
you may need a _Custom Type Adapter_ for Marshalling to JSON or Unmarshalling from JSON.
387
+
Moshi has it covered for you with its advanced adapter mechanism and ReṼoman accepts Moshi adapters.
388
+
Checkout these methods that help us interop between Postman and JVM:
389
+
390
+
==== `globalSkipTypes()`
391
+
392
+
There may be a POJO that inherits or contains legacy types that are hard or impossible to serialize.
393
+
ReṼoman lets you serialize only types that matter, through `globalSkipTypes`,
394
+
where you can filter out these legacy types from Marshalling/Unmarshalling
395
+
396
+
==== `requestConfig()`
397
+
398
+
* Configure Moshi adapters to unmarshall/deserialize _Request_ JSON payload to a POJO on certain steps.
399
+
* You may use the bundled static factory methods named `RequestConfig.unmarshallResponse()` for expressiveness.
400
+
* You can pass a `PreTxnStepPick` which is a `Predicate` used
401
+
to qualify a step whose Request JSON payload needs to be unmarshalled/deserialized.
402
+
* If you have set up `requestConfig()` once, wherever you wish to access the request in your <<#_pre_step_and_post_step_hooks,Pre-Step Hooks>>, you can call `stepReport.responseInfo.get().<TypeT>getTypedTxnObj()` which returns a Strong type to conveniently assert.
403
+
* If you don't pass anything in this config, Moshi unmarshalls into default data structures like `LinkedHashMap`
404
+
405
+
==== `responseConfig()`
406
+
407
+
* Configure Moshi adapters to unmarshall/deserialize _Response_ JSON payload to a POJO on certain steps.
408
+
* You can configure separate adapters for success and error response. Success or Error response is determined by default with HTTP Status Code (SUCCESSFUL: `200 < = statusCode < = 299`).
409
+
* Use bundled static factory methods like `ResponseConfig.unmarshallSuccessResponse()` and `ResponseConfig.unmarshallErrorResponse()` for expressiveness.
410
+
* You can pass a `PostTxnStepPick` which is a `Predicate` used
411
+
to qualify a step whose Response JSON payload needs to be unmarshalled/deserialized.
412
+
* If you have set up `responseConfig()` once, wherever you wish to access or assert the response in your <<#_pre_step_and_post_step_hooks,Post-Step Hooks>>, you can call `stepReport.responseInfo.get().<TypeT>getTypedTxnObj()` which returns a Strong type to conveniently assert.
413
+
* If you don't pass anything in this config, Moshi unmarshalls into default data structures like `LinkedHashMap`
385
414
386
415
[TIP]
387
416
====
388
-
Success or Error response is determined by default with HTTP Status Code (SUCCESSFUL = `200 <=statusCode <=299`). There may be a scenario
417
+
* There may be a scenario
389
418
that you cannot depend on HTTP Status Code to distinguish between Success or Error.
390
-
In such a case,
419
+
* In such a case,
391
420
you can leverage a bundled Moshi factory link:{sourcedir}/com/salesforce/revoman/input/json/factories/DiMorphicAdapter.kt[DiMorphicAdapter]
that deals with it dynamically based on a `boolean` attribute value in the response JSON.
422
+
See `DiMorphicAdapter` in action from the test `compositeGraphResponseDiMorphicMarshallUnmarshall()` in link:{testdir}/com/salesforce/revoman/input/json/JsonPojoUtilsTest.java[JsonPojoUtilsTest].
423
+
* You may also refer to link:https://square.github.io/moshi/1.x/moshi-adapters/adapters/com.squareup.moshi.adapters/-polymorphic-json-adapter-factory/index.html[PolymorphicJsonAdapterFactory] for Marshalling/Unmarshalling based on `String` type attribute.
395
424
====
396
425
397
-
** `globalCustomTypeAdapters` — For types present as part of request/response payload anywhere
398
-
* ReṼoman also comes bundled with link:{sourcedir}/com/salesforce/revoman/input/json/JsonReaderUtils.kt[JSON Reader utils] and link:{sourcedir}/com/salesforce/revoman/input/json/JsonWriterUtils.kt[JSON Writer utils] to help build Moshi adapters.
These adapters are used for marshalling/unmarshalling request/response payload for any step.
429
+
These compliment the custom adapters setup in `requestConfig()` or `responseConfig()`
430
+
431
+
==== JSON Reader/Writer Utils to build Moshi adapters
432
+
433
+
ReṼoman also comes
434
+
bundled with link:{sourcedir}/com/salesforce/revoman/input/json/JsonReaderUtils.kt[JSON Reader utils] and link:{sourcedir}/com/salesforce/revoman/input/json/JsonWriterUtils.kt[JSON Writer utils]
435
+
to help build Moshi adapters.
436
+
437
+
TIP: Refer link:{integrationtestdir}/com/salesforce/revoman/integration/core/pq/adapters/ConnectInputRepWithGraphAdapter.java[ConnectInputRepWithGraphAdapter] on how these utils come in handy in building an advanced Moshi adapter
402
438
403
439
==== JSON POJO Utils
404
440
405
-
The bundled link:{sourcedir}/com/salesforce/revoman/input/json/JsonPojoUtils.kt[JSON POJO Utils] can be used to directly convert JSON to POJO and vice versa.
441
+
The bundled link:{sourcedir}/com/salesforce/revoman/input/json/JsonPojoUtils.kt[JSON POJO Utils] can be used to directly to convert JSON to POJO and vice versa.
You can read an environment variable value as a Strong type.
454
+
See it in action: `getTypedObj()`
455
+
test from link:{testdir}/com/salesforce/revoman/output/postman/PostmanEnvironmentTest.java[PostmanEnvironmentTest]
456
+
415
457
=== Execution Control
416
458
417
459
The configuration offers methods through which the execution strategy can be controlled without making any changes to the template:
@@ -430,8 +472,8 @@ A hook lets you fiddle with the execution by plugging in your custom JVM code be
430
472
You can pass a `PreTxnStepPick/PostTxnStepPick` which is a `Predicate` used
431
473
to qualify a step for Pre-Step/Post-Step Hook respectively.
432
474
ReṼoman comes
433
-
bundled with some predicates under the namespace `PreTxnStepPick.PickUtils`/`PostTxnStepPick.PickUtils` e.g `beforeStepContainingURIPathOfAny`,
434
-
`afterStepName` etc. If those don't fit your needs, you can write your own custom predicates like below:
475
+
bundled with some predicates under the namespace `PreTxnStepPick.PickUtils`/`PostTxnStepPick.PickUtils` e.g `beforeStepContainingURIPathOfAny()`,
476
+
`afterStepName()` etc. If those don't fit your needs, you can write your own custom predicates like below:
435
477
436
478
[source,java,indent=0,tabsize=2,options="nowrap"]
437
479
----
@@ -457,7 +499,7 @@ Add them to the config as below:
457
499
)
458
500
----
459
501
460
-
* You can do things like assertion on the rundown, response validation,
502
+
* You can do things like assertion on the rundown, <<#_response_validations,Response Validations>>,
461
503
or even <<#_mutable_environment,mutate the environment>> with a value you programmatically derived,
462
504
such that the execution of later steps picks up those changes.
463
505
* Reserve hooks for plugging in your custom code or asserting and fail-fast in the middle of execution.
@@ -475,6 +517,7 @@ Instead, you have a Java utility to generate/create it.
475
517
You can invoke the utility in a pre-hook of a step and set the value in `rundown.mutableEnv`,
476
518
so the later steps can pick up value for `+{{xyzId}}+` variable from the environment.
477
519
520
+
[#_response_validations]
478
521
==== Response Validations
479
522
480
523
* Post-Hooks are the best place to validate response right after the step.
@@ -517,7 +560,7 @@ image::node_modules.png[]
517
560
* If `node_modules` is ignored on your git repo, you can force-add to check in using the command `git add -all -f <path>/node_modules`
518
561
====
519
562
520
-
CAUTION: The recommendation is not to add too much code in <<Pre-req and Post-res scripts>>, as they not intuitive to troubleshoot through debugging. Use it for simple operations like set environment variables and use <<#_pre_step_and_post_step_hooks,Pre-Step /Post-Step Hooks>> for any non-trivial operations, which are intuitive to debug.
563
+
CAUTION: The recommendation is not to add too much code in <<Pre-req and Post-res scripts>>, as it's not intuitive to troubleshoot through debugging. Use it for simple operations that can be understood without debugging, and use <<#_pre_step_and_post_step_hooks,Pre-Step /Post-Step Hooks>> for any non-trivial operations, which are intuitive to debug.
0 commit comments