JSON handling
The Navida App consumes a lot of JSON data from multiple sources, including aok-config, plugin-config, and API responses. While simple in theory, in practice it's a complex task—especially when handling edge cases like missing or invalid data.
As of today, there are two mechanisms in place to process JSON: kotlinx.serialization and Google’s Gson library. The former is widely used in the open-contract library, including all Backend API communication. On the other hand, the Navida plugins-repository revolves around Gson. This is due to the API exposed by PluginConfigManager, which delivers plugin-config as a string.
It's crucial to note that these two libraries handle Kotlin data classes differently—see commons/src/test/java/de/ey/commons/utils/TestJsonDecoding.kt for details. This leads to confusion among developers, unnecessary nullability, and app crashes due to uncaught exceptions.
To address these issues, new APIs have been added to PluginConfigManager. See below for details.
Recommended APIs
inline fun <reified T> getPluginConfigOrDefault(pluginId: String, default: T): T
Returns a T
object if parsing was successful, or default
if any exception was thrown. This should be the primary way to work with plugin-configs.
inline fun <reified T> getPluginConfigOrNull(pluginId: String): T?
Returns a T
object if parsing was successful, or null otherwise. Use this when parsing failure needs to be handled separately.
Migration guide
As an example, consider AokSelectionRepositoryImpl
. The following code:
override fun getAokSelectionPluginConfig(): AokSelectionPluginConfig? {
val envConfig = Gson().fromJson(
pluginConfigManager.getPluginConfig(AokSelectionPlugin.getInstance().identifier),
AokSelectionPluginConfig::class.java,
)
return envConfig
}
should be simplified to:
override fun getAokSelectionPluginConfig(): AokSelectionPluginConfig {
return pluginConfigManager.getPluginConfigOrDefault(
PluginIdentifier.AokSelection.identifier, AokSelectionPluginConfig()
)
}
At the same time, data class
es representing config should be annotated with @Serializable
:
@Serializable
data class AokSelectionPluginConfig(
@SerialName("aokId") val aokId: String = "",
....
)
defaultJson
To deal with any JSON data that is not coming from the PluginConfigManager
, defaultJson
static object is there to help.
TODO - debugging docs repo build pipeline