Type Safety
The Postman V2/V3 input format operates purely with JSON.
When that JSON crosses into the JVM, unmarshalling/deserialization of JSON into a POJO (and vice versa) is what lets you write type-safe JVM orchestration code, and it greatly enhances the debugging experience on the JVM.
ReṼoman internally uses a modern JSON library called Moshi. Simple types whose JSON structure aligns with the POJO data structure can directly be converted. But when the JSON structure may not align with the POJO, you may need a Custom Type Adapter for Marshalling to JSON or Unmarshalling from JSON. Moshi has it covered for you with its advanced adapter mechanism, and ReṼoman accepts Moshi adapters via the config methods below. The best part of Moshi is, you can write adapters without any need to add annotations (you can add them if you want). This helps even if you have no control over the POJOs you are operating on.
globalSkipTypes()
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.
requestConfig()
-
Configure Moshi adapters to unmarshall/deserialize Request JSON payload to a POJO on certain steps.
-
You may use the bundled static factory methods named
RequestConfig.unmarshallRequest()for expressiveness. -
You can pass a
PreTxnStepPickwhich is aPredicateused to qualify a step whose Request JSON payload needs to be unmarshalled/deserialized. -
If you have set up
requestConfig()once in the config, wherever you wish to read or assert the request, you can callstepReport.requestInfo.get().<TypeT>getTypedTxnObj()which returns your request JSON as a Strong type.
responseConfig()
-
Configure Moshi adapters to unmarshall/deserialize Response JSON payload to a POJO on certain steps.
-
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). -
Use bundled static factory methods like
ResponseConfig.unmarshallSuccessResponse()andResponseConfig.unmarshallErrorResponse()for expressiveness. -
You can pass a
PostTxnStepPickwhich is aPredicateused to qualify a step whose Response JSON payload needs to be unmarshalled/deserialized. -
If you have set up
responseConfig()once, wherever you wish to read or assert the response, you can callstepReport.responseInfo.get().<TypeT>getTypedTxnObj()which returns your response JSON as a Strong type.
|
globalCustomTypeAdapters()
-
These come handy when the same POJO/Data structure (e.g.
ID) is present across multiple Request or Response POJOs. These adapters compliment the custom adapters setup inrequestConfig()orresponseConfig()wherever these types are present.
If you don’t configure any adapters, you can either pass the adapter at runtime using the overload stepReport.requestInfo.get().<TypeT>getTypedTxnObj(type, customAdapters, customAdaptersForType) or Moshi by default unmarshalls the step’s request/response JSON into a generic data structures like LinkedHashMap.
|
All these adapters supplied from various config methods per a revUp() execution are appended to the same Moshi instance created in that thread. Read more about Moshi adapter composition. This means you don’t have to supply the adapters repeatedly for the same type. This also means your adapters may get overridden unexpectedly. Keep this in mind while troubleshooting any serialize/deserialize issues. If you wish to manage Moshi yourself, you can get a copy of internal Moshi via pokeRundown.mutableEnv.moshiReVoman().internalMoshiCopy().
|
JSON Reader/Writer Utils to build Moshi adapters
ReṼoman also comes bundled with JSON Reader utils and JSON Writer utils to help build Moshi adapters.
| Refer ConnectInputRepWithGraphAdapter on how these utils come in handy in building an advanced Moshi adapter. |
JSON POJO Utils
The bundled JSON POJO Utils can be used to directly convert JSON to POJO and vice versa.
|
See in Action: |
Type-safe request/response objects are most useful inside hooks, where you assert on them right after a step, and when you mutate the environment with a programmatically derived value.