6.3 JSON and Moshi
Last updated
Last updated
JSON, or JavaScript Object Notation, is a way of representing data. While its syntax comes from JavaScript, it is still language independent.
When it comes to networking, JSON is typically used in two cases. One is to POST data to a server. The other is a server’s response to the client. Servers may choose to use other formats, like XML, so don’t assume that every server will use JSON (but it is the most common type of format).
There are two main advantages when using JSON with networking. It's very easy for a client to parse the file. Also, it is easily formatted in a way that’s easy for us humans to read.
Above is a sample of JSON data (if you're familiar with python, it looks very similar to a dictionary).
The data consists of pairs of keys and values. There is a colon character separating each key and value. In the example, base is a key, and GBP is the corresponding value. A comma separates each pair.
A value can be a string in double quotes, or a number, or true or false or null, or another object or an array. These structures can be nested (e.g. I can have an array be a list of objects).
Information within curly braces is an object. In the example above, the value for the rates key is another object, containing more pairs.
Above is an example of a JSON array.
See how this starts and ends with square brackets? This indicates that the data is an array. Each object is a separate ‘record’ or element in the array. Each object in the array is also separated by a comma.
For the sake of example, the array is a list of objects but the array can be a list of any of the valid JSON types (you can also have arrays of many different types).
From this you can kind of see how tedious it would be to try and iterate through an array like this to parse the JSON objects (which is where Moshi comes into play to make this process easier for us)!
Many times what's returned from networking calls are class objects represented as JSONs, which can be a headache to try and parse manually (and often times isn't as efficient). In comes Moshi, which is a handy library also developed by Square used for converting between JSON and Kotlin objects. In tandem they make networking in Android super easy!
In a language like python, we would need to pip install x
and then later import x
but in Kotlin we have a much more complicated file structure and system so we do the following (typically):
In the build.gradle we have to add dependencies to "install" the library
Add the following dependencies in your module-level build.gradle file:
We're gonna be referring to the classes below as we introduce Moshi:
Moshi gives us JSONs like this that we can read from and write to:
Pay special note that the names of our fields in our data class should correspond to what we expect to receive from our response. Check out this section to see how we can change that!
If we want to convert JSONs into objects of our Kotlin class, we can do something like what's below:
If we want to go the other way around:
Moshi has built-in support for reading and writing Kotlin's core data types:
Primitives (int, float, char...)
Arrays, Collections, Lists, Sets, and Maps
Strings
Enums
Say we have a JSON string of this structure:
We can now use Moshi to parse the JSON string into a List<Card>:
Moshi works best when your JSON objects and Java or Kotlin classes have the same structure. But when they don't, Moshi has annotations to customize data binding.
Use @Json
to specify how Kotlin properties map to JSON names. This is necessary when the JSON name contains spaces or other characters that aren’t permitted in Kotlin property names. For example, this JSON has a field name containing a space:
We can't have spaces in our Kotlin property names, so we can create a mapping of how Moshi should convert ourselves: