<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:sy="http://purl.org/rss/1.0/modules/syndication/">
	<channel>
		<title>A Kotlin-First JSON API Library – JsonApiX | Infinum</title>
		<atom:link href="https://infinum.com/blog/a-kotlin-first-json-api-library-jsonapix/feed/" rel="self" type="application/rss+xml" />
		<link>https://infinum.com/blog/a-kotlin-first-json-api-library-jsonapix/</link>
		<description>Building digital products</description>
		<lastBuildDate>Fri, 03 Apr 2026 12:58:20 +0000</lastBuildDate>
		<sy:updatePeriod>hourly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>

					<item>
				<image>
					<url>25200https://infinum.com/uploads/2022/06/JsonX-optimized.webp</url>
				</image>
				<title>A Kotlin-First JSON API Library – JsonApiX</title>
				<link>https://infinum.com/blog/a-kotlin-first-json-api-library-jsonapix/</link>
				<pubDate>Fri, 03 Jun 2022 09:54:05 +0000</pubDate>
				<dc:creator>Stjepan Banek</dc:creator>
				<guid isPermaLink="false">https://infinum.com/?p=25200</guid>
				<description>
					<![CDATA[<p>The Kotlin community was missing a fresh, easy-to-use and Kotlin-first JSON:API implementation. </p>
<p>The post <a href="https://infinum.com/blog/a-kotlin-first-json-api-library-jsonapix/">A Kotlin-First JSON API Library – JsonApiX</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</description>
				<content:encoded>
					<![CDATA[<div
	class="wrapper"
	data-id="es-324"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-92">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-95"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-93">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-94'
	>
	<a href="https://jsonapi.org/">JSON:API is a widely used specification</a> for modeling client–server API&#8217;s. It’s built on top of the JSON notation standard, to make sharing objects with relationships and all other relevant information such as errors, links, and meta data standardized. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-98"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-96">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-97'
	>
	However, in Kotlin, it has been poorly covered by libraries that would make the use of JSON:API easier for the developer.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-100"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-highlighted-text">
	<p	class='typography typography--size-24-text js-typography block-highlighted-text__typography'
	data-id='es-99'
	>
	When we set out on this project, we believed that the Kotlin community was missing a fresh, easy-to-use and Kotlin-first JSON:API implementation.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-103"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-101">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-102'
	>
	While considering how to make the usage as simple as possible, we decided to go with the annotation processor and code generation approach. The goal was to come up with a set of annotations that would make the bridge between Kotlin classes and JSON:API, without any additional effort. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-106"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-104">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-105'
	>
	As will be shown in this article, our <a href="https://github.com/infinum/kotlin-jsonapix">JsonApiX<strong> </strong>library</a><strong> </strong>has achieved just that.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-109"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-107">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-108'
	>
	General info</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-112"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-110">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-111'
	>
	JsonApiX is an annotation processor library made on top of the <a href="https://github.com/Kotlin/kotlinx.serialization/blob/master/docs/serialization-guide.md">Kotlinx serialization</a>, to make implementing JSON:API specification much easier. With the use of just a few annotations, it generates JSON:API wrappers for the Kotlin classes.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-115"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-113">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-114'
	>
	Wrappers are modeled in a way to follow the JSON:API specification format, using the annotated class’s properties to model the data and relationships part. They are serializable, so parsing in both directions is supported.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-118"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-116">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-117'
	>
	The library also has a retrofit module, with a converter to support the API implementations.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-121"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-119">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-120'
	>
	It was built for Kotlin, so it can be used on all Kotlin based projects such as Android apps and Kotlin multiplatform apps.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-124"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-122">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-123'
	>
	Basic usage</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-127"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-125">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-126'
	>
	Let’s take the example of a simple class called <code>Book</code>.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-129"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-java github-light" data-language="java" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">@</span><span class="token" style="color: #d73a49;">JsonApiX</span><span class="token">(</span><span class="token" style="color: #005cc5;">type</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">book</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">@</span><span class="token" style="color: #d73a49;">Serializable</span><span class="token">
</span></span><span class="line"><span class="token">data </span><span class="token" style="color: #d73a49;">class</span><span class="token"> </span><span class="token" style="color: #6f42c1;">Book</span><span class="token">(
</span></span><span class="line"><span class="token">   val name: String,
</span></span><span class="line"><span class="token">   val pageCount: Int
</span></span><span class="line"><span class="token">)
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-132"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-130">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-131'
	>
	<code>Book</code> has two simple parameters: <code>name</code> and <code>pageCount</code>.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-135"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-133">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-134'
	>
	Every class annotated with <code>@JsonApiX</code> needs to also be annotated with <code>@Serializable</code> , because JsonApiX is leveraging the Kotlinx serialization to serialize and deserialize classes.&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-138"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-136">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-137'
	>
	<code>@JsonApiX</code> takes a <code>type</code> parameter, which is one of the mandatory JSON:API parameters, and its value will be used as the value for the key <code>type</code> in the output.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-141"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-139">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-140'
	>
	When we annotate a class with the <code>@JsonApiX</code> annotation, the processor will generate the implementations of a number of interfaces, based on the annotated class. They are made to convert it to the JSON:API format and offer a way to parse it.&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-144"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-142">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-143'
	>
	Two most important interfaces are shown below.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-146"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-java github-light" data-language="java" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">interface</span><span class="token"> </span><span class="token" style="color: #6f42c1;">JsonApiX</span><span class="token">&lt;</span><span class="token" style="color: #d73a49;">out</span><span class="token"> </span><span class="token" style="color: #d73a49;">Model</span><span class="token">&gt;</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">   val data</span><span class="token" style="color: #d73a49;">:</span><span class="token"> </span><span class="token" style="color: #24292e;">ResourceObject</span><span class="token">&lt;</span><span class="token" style="color: #d73a49;">Model</span><span class="token">&gt;</span><span class="token" style="color: #d73a49;">?</span><span class="token">
</span></span><span class="line"><span class="token">   val included</span><span class="token" style="color: #d73a49;">:</span><span class="token"> </span><span class="token" style="color: #24292e;">List</span><span class="token">&lt;</span><span class="token" style="color: #24292e;">ResourceObject</span><span class="token">&lt;</span><span class="token">*</span><span class="token">&gt;</span><span class="token">&gt;</span><span class="token" style="color: #d73a49;">?</span><span class="token">
</span></span><span class="line"><span class="token">   val errors</span><span class="token" style="color: #d73a49;">:</span><span class="token"> </span><span class="token" style="color: #24292e;">List</span><span class="token">&lt;</span><span class="token" style="color: #d73a49;">Error</span><span class="token">&gt;</span><span class="token" style="color: #d73a49;">?</span><span class="token">
</span></span><span class="line"><span class="token">   val links</span><span class="token" style="color: #d73a49;">:</span><span class="token"> Links</span><span class="token" style="color: #d73a49;">?</span><span class="token">
</span></span><span class="line"><span class="token">   val meta</span><span class="token" style="color: #d73a49;">:</span><span class="token"> Meta</span><span class="token" style="color: #d73a49;">?</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-149"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-147">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-148'
	>
	<code>JsonApiX</code> interface is a root-level wrapper for a class. Data property wraps the primitive attributes of the original class and relationship references. Included array contains the data of the relationships if any are present. Other properties of this interface are optional fields from the JSON:API specification. Every generated implementation is serializable, allowing the serialization and deserialization of all the parameters from the specification.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-152"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-150">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-151'
	>
	Along with the wrappers, the library also generates helper functions and extensions to support the serialization/deserialization processes. Aiming to prevent the developers from having to know and use them, we’ve come up with the idea of an adapter. For each annotated class, an adapter implementation will be generated, as a composition of all the operations needed in the serialization/deserialization process.&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-155"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-153">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-154'
	>
	Here is the interface we use for the adapter implementations with its most important methods.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-157"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-java github-light" data-language="java" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">interface</span><span class="token"> </span><span class="token" style="color: #6f42c1;">TypeAdapter</span><span class="token">&lt;</span><span class="token" style="color: #d73a49;">Model</span><span class="token">&gt;</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">   </span><span class="token">fun</span><span class="token"> </span><span class="token" style="color: #6f42c1;">convertFromStrin</span><span class="token" style="color: #6f42c1;">g</span><span class="token">(</span><span class="token" style="color: #e36209;">input</span><span class="token">: </span><span class="token" style="color: #e36209;">String</span><span class="token">)</span><span class="token">: Model
</span></span><span class="line"><span class="token">   </span><span class="token">fun</span><span class="token"> </span><span class="token" style="color: #6f42c1;">convertToStrin</span><span class="token" style="color: #6f42c1;">g</span><span class="token">(</span><span class="token" style="color: #e36209;">input</span><span class="token">: </span><span class="token" style="color: #e36209;">Model</span><span class="token">)</span><span class="token">: String
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-160"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-158">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-159'
	>
	To get the type adapter for your specific class, use the generated TypeAdapterFactory class.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-162"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-java github-light" data-language="java" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #6a737d;">//</span><span class="token" style="color: #6a737d;"> Gets adapter for a single instance of Book</span><span class="token" style="color: #6a737d;">
</span></span><span class="line"><span class="token">val adapter </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #6f42c1;">TypeAdapterFactory</span><span class="token">(</span><span class="token">)</span><span class="token">.</span><span class="token" style="color: #6f42c1;">getAdapter</span><span class="token">(</span><span class="token">Book</span><span class="token" style="color: #d73a49;">:</span><span class="token" style="color: #d73a49;">:</span><span class="token">class</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #6a737d;">//</span><span class="token" style="color: #6a737d;"> Gets adapter for a list of Book instances</span><span class="token" style="color: #6a737d;">
</span></span><span class="line"><span class="token">val listAdapter </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #6f42c1;">TypeAdapterFactory</span><span class="token">(</span><span class="token">)</span><span class="token">.</span><span class="token" style="color: #6f42c1;">getListAdapter</span><span class="token">(</span><span class="token">Book</span><span class="token" style="color: #d73a49;">:</span><span class="token" style="color: #d73a49;">:</span><span class="token">class</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #24292e;">adapter</span><span class="token">.</span><span class="token" style="color: #6f42c1;">convertToString</span><span class="token">(</span><span class="token">book</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #6a737d;">//</span><span class="token" style="color: #6a737d;"> Produces JSON API String from a Book instance</span><span class="token" style="color: #6a737d;">
</span></span><span class="line"><span class="token" style="color: #24292e;">adapter</span><span class="token">.</span><span class="token" style="color: #6f42c1;">convertFromString</span><span class="token">(</span><span class="token">input</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #6a737d;">//</span><span class="token" style="color: #6a737d;"> Produces Book instance from JSON:API String</span><span class="token" style="color: #6a737d;">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #24292e;">listAdapter</span><span class="token">.</span><span class="token" style="color: #6f42c1;">convertToString</span><span class="token">(</span><span class="token">books</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #6a737d;">//</span><span class="token" style="color: #6a737d;"> Produces JSON:API String from a Book list</span><span class="token" style="color: #6a737d;">
</span></span><span class="line"><span class="token" style="color: #24292e;">listAdapter</span><span class="token">.</span><span class="token" style="color: #6f42c1;">convertFromString</span><span class="token">(</span><span class="token">input</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #6a737d;">//</span><span class="token" style="color: #6a737d;"> Produces Book list from JSON:API String</span><span class="token" style="color: #6a737d;">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-165"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-163">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-164'
	>
	Now, let’s extend our model and take a look at how to handle relationships in our classes. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-167"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-java github-light" data-language="java" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">@</span><span class="token" style="color: #d73a49;">JsonApiX</span><span class="token">(</span><span class="token" style="color: #005cc5;">type</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">book</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">@</span><span class="token" style="color: #d73a49;">Serializable</span><span class="token">
</span></span><span class="line"><span class="token">data </span><span class="token" style="color: #d73a49;">class</span><span class="token"> </span><span class="token" style="color: #6f42c1;">Book</span><span class="token">(
</span></span><span class="line"><span class="token">   val name: String,
</span></span><span class="line"><span class="token">   val pageCount: Int,
</span></span><span class="line"><span class="token">   @HasOne(type = &quot;author&quot;)
</span></span><span class="line"><span class="token">   val author: Author,
</span></span><span class="line"><span class="token">   @HasMany(type = &quot;character&quot;)
</span></span><span class="line"><span class="token">   val characters: List</span><span class="token">&lt;</span><span class="token" style="color: #d73a49;">Character</span><span class="token">&gt;</span><span class="token">
</span></span><span class="line"><span class="token">)
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-170"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-168">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-169'
	>
	Our Book now has an author and a list of characters. Both of these attributes are classes themselves, so they need to be treated as relationships.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-172"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-highlighted-text">
	<p	class='typography typography--size-20-text js-typography block-highlighted-text__typography'
	data-id='es-171'
	>
	Important note: Relationship models need to also be annotated with both @JsonApiX and @Serializable. The type parameter in @JsonApiX of the relationship model needs to match the one in @HasOne/@HasMany annotations. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-175"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-173">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-174'
	>
	Generated wrappers and adapters will now account for the relationships in serialization and deserialization. No additional work is needed.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-177"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-highlighted-text">
	<p	class='typography typography--size-20-text js-typography block-highlighted-text__typography'
	data-id='es-176'
	>
	Important note: When deserializing relationships, JsonApiX relies on the included array from the JSON:API specification. If the relationship is non-nullable and missing from the included array, a JsonApiXMissingArgumentException will be thrown.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-180"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-178">
	<h3	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-179'
	>
	Nullability</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-183"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-181">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-182'
	>
	Our Book model looks great now, right? However, do all books necessarily have characters? I don&#8217;t think so, and I&#8217;m speaking from personal experience – as a person who read a couple of physics books while studying. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-186"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-184">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-185'
	>
	Let’s make a small change in our Book model and make the characters list nullable.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-188"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-java github-light" data-language="java" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">@</span><span class="token" style="color: #d73a49;">JsonApiX</span><span class="token">(</span><span class="token" style="color: #005cc5;">type</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">book</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">@</span><span class="token" style="color: #d73a49;">Serializable</span><span class="token">
</span></span><span class="line"><span class="token">data </span><span class="token" style="color: #d73a49;">class</span><span class="token"> </span><span class="token" style="color: #6f42c1;">Book</span><span class="token">(
</span></span><span class="line"><span class="token">   val name: String,
</span></span><span class="line"><span class="token">   val pageCount: Int,
</span></span><span class="line"><span class="token">   @HasOne(type = &quot;author&quot;)
</span></span><span class="line"><span class="token">   val author: Author,
</span></span><span class="line"><span class="token">   @HasMany(type = &quot;character&quot;)
</span></span><span class="line"><span class="token">   val characters: List</span><span class="token">&lt;</span><span class="token" style="color: #d73a49;">Character</span><span class="token">&gt;</span><span class="token">?
</span></span><span class="line"><span class="token">)
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-191"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-189">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-190'
	>
	As I mentioned before, all non-nullable relationships must be present in the included array of the JSON:API input. Otherwise, the deserialization process will fail.&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-194"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-192">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-193'
	>
	However, nullable relationships do not suffer the same fate. They will simply be assigned to <code>null</code> if the input is missing their data.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-197"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-195">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-196'
	>
	We’ve made our deserialization process with nullable properties in mind, so it’s safe to have nullable attributes, both primitive and relationships. The JSON:API input can be deserialized without their values.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-200"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-198">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-199'
	>
	For example, the following JSON:API input:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-202"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-java github-light" data-language="java" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">
</span></span><span class="line"><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">   </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">data</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #d73a49;">:</span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">      </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">type</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #d73a49;">:</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">book</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">,</span><span class="token">
</span></span><span class="line"><span class="token">      </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">id</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #d73a49;">:</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">1</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">,</span><span class="token">
</span></span><span class="line"><span class="token">      </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">attributes</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #d73a49;">:</span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">         </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">name</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #d73a49;">:</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">The Fellowship Of The Ring</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">,</span><span class="token">
</span></span><span class="line"><span class="token">         </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">pageCount</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #d73a49;">:</span><span class="token" style="color: #005cc5;">432</span><span class="token">
</span></span><span class="line"><span class="token">      </span><span class="token">}</span><span class="token">,</span><span class="token">
</span></span><span class="line"><span class="token">      </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">relationships</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #d73a49;">:</span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">         </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">author</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #d73a49;">:</span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">            </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">data</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #d73a49;">:</span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">               </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">type</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #d73a49;">:</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">author</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">,</span><span class="token">
</span></span><span class="line"><span class="token">               </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">id</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #d73a49;">:</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">4</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">
</span></span><span class="line"><span class="token">            </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">         </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">      </span><span class="token">}</span><span class="token">,</span><span class="token">
</span></span><span class="line"><span class="token">      </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">included</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #d73a49;">:</span><span class="token">[</span><span class="token">
</span></span><span class="line"><span class="token">         </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">            </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">type</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #d73a49;">:</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">author</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">,</span><span class="token">
</span></span><span class="line"><span class="token">            </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">id</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #d73a49;">:</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">4</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">,</span><span class="token">
</span></span><span class="line"><span class="token">            </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">attributes</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #d73a49;">:</span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">               </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">name</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #d73a49;">:</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">J.R.R. Tolkien</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">
</span></span><span class="line"><span class="token">            </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">         </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">      </span><span class="token">]</span><span class="token">
</span></span><span class="line"><span class="token">   </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-205"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-203">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-204'
	>
	Will be successfully parsed to a Book instance with characters list assigned to <code>null</code>.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-208"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-206">
	<h3	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-207'
	>
	Errors</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-211"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-209">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-210'
	>
	According to the JSON:API specification, each object should have an optional errors array. The following interface is used as a root-level wrapper for JSON:API responses. It contains a nullable errors list.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-213"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-java github-light" data-language="java" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">interface</span><span class="token"> </span><span class="token" style="color: #6f42c1;">JsonApiX</span><span class="token">&lt;</span><span class="token" style="color: #d73a49;">out</span><span class="token"> </span><span class="token" style="color: #d73a49;">Model</span><span class="token">&gt;</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    val data</span><span class="token" style="color: #d73a49;">:</span><span class="token"> </span><span class="token" style="color: #24292e;">ResourceObject</span><span class="token">&lt;</span><span class="token" style="color: #24292e;">M</span><span class="token" style="color: #d73a49;">odel</span><span class="token">&gt;</span><span class="token" style="color: #d73a49;">?</span><span class="token">
</span></span><span class="line"><span class="token">    val included</span><span class="token" style="color: #d73a49;">:</span><span class="token"> </span><span class="token" style="color: #24292e;">List</span><span class="token">&lt;</span><span class="token" style="color: #24292e;">R</span><span class="token" style="color: #24292e;">esourceObject</span><span class="token">&lt;</span><span class="token">*</span><span class="token">&gt;</span><span class="token">&gt;</span><span class="token" style="color: #d73a49;">?</span><span class="token">
</span></span><span class="line"><span class="token">    val errors</span><span class="token" style="color: #d73a49;">:</span><span class="token"> </span><span class="token" style="color: #24292e;">List</span><span class="token">&lt;</span><span class="token" style="color: #24292e;">E</span><span class="token" style="color: #d73a49;">rror</span><span class="token">&gt;</span><span class="token" style="color: #d73a49;">?</span><span class="token">
</span></span><span class="line"><span class="token">    val links</span><span class="token" style="color: #d73a49;">:</span><span class="token"> Links</span><span class="token" style="color: #d73a49;">?</span><span class="token">
</span></span><span class="line"><span class="token">    val meta</span><span class="token" style="color: #d73a49;">:</span><span class="token"> Meta</span><span class="token" style="color: #d73a49;">?</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-216"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-214">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-215'
	>
	A single error is modeled to wrap the most common arguments of an error. In the future, we plan to extend the error model with some optional fields, and give the developers an ability to model their custom errors.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-218"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-java github-light" data-language="java" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">class</span><span class="token"> </span><span class="token" style="color: #6f42c1;">Error</span><span class="token">(
</span></span><span class="line"><span class="token">    val code: String,
</span></span><span class="line"><span class="token">    val title: String,
</span></span><span class="line"><span class="token">    val detail: String,
</span></span><span class="line"><span class="token">    val status: String
</span></span><span class="line"><span class="token">)
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-221"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-219">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-220'
	>
	When using Retrofit in the event of a network error, a <code>HttpException</code> will be thrown. To extract the <code>Error</code> model from a response, you can use the <code>HttpException.asJsonXHttpException()</code> extension, which will then return a <code>JsonXHttpException</code>, containing the original response as well as the errors list.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-223"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-java github-light" data-language="java" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">try</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    val book </span><span class="token" style="color: #d73a49;">=</span><span class="token"> io </span><span class="token">{</span><span class="token"> </span><span class="token" style="color: #24292e;">sampleApiService</span><span class="token" style="color: #6f42c1;">.fetchBo</span><span class="token" style="color: #6f42c1;">o</span><span class="token">k(</span><span class="token">)</span><span class="token"> </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token"> </span><span class="token" style="color: #d73a49;">catch</span><span class="token"> </span><span class="token">(</span><span class="token" style="color: #24292e;">exception</span><span class="token">: </span><span class="token" style="color: #e36209;">HttpException</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    val errors </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #24292e;">exception</span><span class="token">.asJsonXHttpException</span><span class="token">(</span><span class="token">)</span><span class="token" style="color: #24292e;">.error</span><span class="token">s</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #6a737d;">//</span><span class="token" style="color: #6a737d;"> Handle errors</span><span class="token" style="color: #6a737d;">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-226"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-224">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-225'
	>
	Advanced usage</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-229"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-227">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-228'
	>
	JSON:API specification includes resources that are not necessarily a part of the original models. For that reason, JsonApiX provides a way to retrieve the links and meta values from the JSON:API input without including those fields in your model. To achieve this, your model needs to extend the <code>JsonApiModel</code> abstract class.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-231"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-java github-light" data-language="java" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">@</span><span class="token" style="color: #d73a49;">JsonApiX</span><span class="token">(</span><span class="token" style="color: #005cc5;">type</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">book</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">@</span><span class="token" style="color: #d73a49;">Serializable</span><span class="token">
</span></span><span class="line"><span class="token">data </span><span class="token" style="color: #d73a49;">class</span><span class="token"> </span><span class="token" style="color: #6f42c1;">Book</span><span class="token">(
</span></span><span class="line"><span class="token">   val name: String,
</span></span><span class="line"><span class="token">   val pageCount: Int,
</span></span><span class="line"><span class="token">   @HasOne(type = &quot;author&quot;)
</span></span><span class="line"><span class="token">   val author: Author,
</span></span><span class="line"><span class="token">   @HasMany(type = &quot;character&quot;)
</span></span><span class="line"><span class="token">   val characters: List</span><span class="token">&lt;</span><span class="token" style="color: #d73a49;">Character</span><span class="token">&gt;</span><span class="token">?
</span></span><span class="line"><span class="token">) : JsonApiModel()
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-234"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-232">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-233'
	>
	<code>JsonApiModel</code> is an abstract class which will provide you with getters and setters for links and meta objects.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-237"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-235">
	<h3	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-236'
	>
	Links</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-240"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-238">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-239'
	>
	JsonApiX currently supports retrieving links from the root object, relationships and resource object(<code>data</code> key) from the JSON:API specification. By default, the links model has the following implementation.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-242"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-java github-light" data-language="java" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">class</span><span class="token"> </span><span class="token" style="color: #6f42c1;">DefaultLinks</span><span class="token">(
</span></span><span class="line"><span class="token">    val self: String? = null,
</span></span><span class="line"><span class="token">    val related: String? = null,
</span></span><span class="line"><span class="token">    val first: String? = null,
</span></span><span class="line"><span class="token">    val last: String? = null,
</span></span><span class="line"><span class="token">    val next: String? = null,
</span></span><span class="line"><span class="token">    val prev: String? = null
</span></span><span class="line"><span class="token">) : Links
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-245"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-243">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-244'
	>
	And they can be retrieved in the following way.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-247"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-java github-light" data-language="java" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #6a737d;">//</span><span class="token" style="color: #6a737d;"> Get root level links</span><span class="token" style="color: #6a737d;">
</span></span><span class="line"><span class="token" style="color: #24292e;">person</span><span class="token">.</span><span class="token" style="color: #6f42c1;">rootLinks</span><span class="token">(</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #6a737d;">//</span><span class="token" style="color: #6a737d;"> Get relationships links</span><span class="token" style="color: #6a737d;">
</span></span><span class="line"><span class="token" style="color: #24292e;">person</span><span class="token">.</span><span class="token" style="color: #6f42c1;">relationshipsLinks</span><span class="token">(</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #6a737d;">//</span><span class="token" style="color: #6a737d;"> Get resource object links</span><span class="token" style="color: #6a737d;">
</span></span><span class="line"><span class="token" style="color: #24292e;">person</span><span class="token">.</span><span class="token" style="color: #6f42c1;">resourceLinks</span><span class="token">(</span><span class="token">)</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-250"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-248">
	<h3	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-249'
	>
	Custom links</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-253"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-251">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-252'
	>
	Developers can define their own custom link models to adapt to their specific requirements. Let&#8217;s take this custom Book links model as an example. Every custom links model must extend the <code>Links</code> interface and have a <code>JsonApiXLinks</code> annotation.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-255"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-java github-light" data-language="java" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">@</span><span class="token" style="color: #d73a49;">Serializable</span><span class="token">
</span></span><span class="line"><span class="token">@</span><span class="token" style="color: #d73a49;">JsonApiXLinks</span><span class="token">(</span><span class="token" style="color: #005cc5;">type</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">book</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">,</span><span class="token"> </span><span class="token" style="color: #005cc5;">placementStrategy</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #24292e;">LinksPlacementStrategy</span><span class="token">.</span><span class="token" style="color: #24292e;">ROOT</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">data </span><span class="token" style="color: #d73a49;">class</span><span class="token"> </span><span class="token" style="color: #6f42c1;">BookLinks</span><span class="token">(
</span></span><span class="line"><span class="token">   val authorBioLink: String,
</span></span><span class="line"><span class="token">   val bookStoreLink: String
</span></span><span class="line"><span class="token">)
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-258"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-256">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-257'
	>
	In this example, the annotation processor will automatically make the root-links type of a <code>Book</code> class to be BookLinks.&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-261"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-259">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-260'
	>
	Developers need to make sure that the <code>type</code> parameter value in <code>JsonApiXLinks</code> matches the one in the <code>JsonApiX</code> annotation of the original model. <br></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-264"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-262">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-263'
	>
	To retrieve them, a generic variant of the <code>rootLinks()</code> method is used.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-266"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-java github-light" data-language="java" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #6a737d;">//</span><span class="token" style="color: #6a737d;"> Gets root level links as a BookLinks instance</span><span class="token" style="color: #6a737d;">
</span></span><span class="line"><span class="token" style="color: #24292e;">person</span><span class="token">.</span><span class="token" style="color: #24292e;">rootLinks</span><span class="token" style="color: #d73a49;">&lt;</span><span class="token">BookLinks</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">(</span><span class="token">)</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-269"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-267">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-268'
	>
	<code>LinksPlacementStartegy</code> enum is used to determine which links from the whole JSON:API object will be replaced by a custom model. It currently supports <code>ROOT</code>, <code>RELATIONSHIPS</code> and <code>DATA</code> links.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-272"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-270">
	<h3	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-271'
	>
	Meta object</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-275"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-273">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-274'
	>
	In JSON:API specification, meta is an optional object. Unlike links, it doesn&#8217;t have a predefined default model. For that reason, in order to use the meta feature, the developer must define a custom meta model for each class with which he wants to use it.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-278"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-276">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-277'
	>
	<br>Let&#8217;s take the <code>BookMeta</code> model as an example. Every custom meta model must extend the <code>Meta</code> interface and have a <code>JsonApiXMeta</code> annotation, with its type parameter matching the one from the <code>JsonApiX</code> annotation of the original model.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-280"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-java github-light" data-language="java" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">@</span><span class="token" style="color: #d73a49;">Serializable</span><span class="token">
</span></span><span class="line"><span class="token">@</span><span class="token" style="color: #d73a49;">JsonApiXMeta</span><span class="token">(</span><span class="token" style="color: #005cc5;">type</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">book</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">data </span><span class="token" style="color: #d73a49;">class</span><span class="token"> </span><span class="token" style="color: #6f42c1;">BookMeta</span><span class="token">(
</span></span><span class="line"><span class="token">   val publisherName: String
</span></span><span class="line"><span class="token">) : Meta
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-283"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-281">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-282'
	>
	In this example, the annotation processor will automatically make the meta type of a <code>Book</code> class to be <code>BookMeta</code>. To retrieve a meta object, a generic variant of the <code>meta()</code> method is used.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-285"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-java github-light" data-language="java" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #6a737d;">//</span><span class="token" style="color: #6a737d;"> Gets the meta object</span><span class="token" style="color: #6a737d;">
</span></span><span class="line"><span class="token" style="color: #24292e;">book</span><span class="token">.</span><span class="token" style="color: #24292e;">meta</span><span class="token" style="color: #d73a49;">&lt;</span><span class="token">BookMeta</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token">(</span><span class="token">)</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-288"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-286">
	<h3	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-287'
	>
	Retrofit</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-291"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-289">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-290'
	>
	To enable the Retrofit integration, JsonApiX generates the converter implementation which can be added to the retrofit builder. It takes an instance of <code>TypeAdapterFactory</code> as a parameter. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-293"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-java github-light" data-language="java" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #24292e;">Retrofit</span><span class="token">.</span><span class="token" style="color: #6f42c1;">Builder</span><span class="token">(</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #6f42c1;">.addConverterFac</span><span class="token" style="color: #6f42c1;">t</span><span class="token" style="color: #6f42c1;">or</span><span class="token">y(</span><span class="token" style="color: #6f42c1;">JsonXConverterFac</span><span class="token" style="color: #6f42c1;">t</span><span class="token" style="color: #6f42c1;">ory</span><span class="token">(</span><span class="token" style="color: #6f42c1;">TypeAdapterFac</span><span class="token" style="color: #6f42c1;">t</span><span class="token" style="color: #6f42c1;">ory</span><span class="token">(</span><span class="token">)</span><span class="token">)</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #6f42c1;">.bas</span><span class="token" style="color: #6f42c1;">e</span><span class="token" style="color: #6f42c1;">Ur</span><span class="token">l(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">https://www.example.com</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #6f42c1;">.b</span><span class="token" style="color: #6f42c1;">u</span><span class="token" style="color: #6f42c1;">il</span><span class="token">d(</span><span class="token">)</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-296"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-294">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-295'
	>
	<code>JsonXConverterFactory</code> converts the input all the way down (or up) to the original model, so there is no need for any additional wrappers in the API service definition. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-298"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-java github-light" data-language="java" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">interface</span><span class="token"> </span><span class="token" style="color: #6f42c1;">SampleApiService</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">@</span><span class="token" style="color: #d73a49;">GE</span><span class="token">T(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">/book</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">fun</span><span class="token"> </span><span class="token" style="color: #6f42c1;">fetch</span><span class="token" style="color: #6f42c1;">B</span><span class="token" style="color: #6f42c1;">ook</span><span class="token">(</span><span class="token">)</span><span class="token">: Book
</span></span><span class="line"><span class="token">    
</span></span><span class="line"><span class="token">    @</span><span class="token" style="color: #6f42c1;">P</span><span class="token" style="color: #6f42c1;">OST</span><span class="token">(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">/create-book</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">fun</span><span class="token"> </span><span class="token" style="color: #6f42c1;">postNew</span><span class="token" style="color: #6f42c1;">B</span><span class="token" style="color: #6f42c1;">ook</span><span class="token">(</span><span class="token" style="color: #d73a49;">@Bod</span><span class="token">y</span><span class="token"> </span><span class="token" style="color: #e36209;">book</span><span class="token">: </span><span class="token" style="color: #e36209;">Book</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-301"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-299">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-300'
	>
	Annotations summary table</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-304"
	 data-animation-target='inner-items'>
		
			<div class="block-group" data-id=es-303>
	
<div
	class="wrapper"
	data-id="es-302"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			
<figure class="wp-block-table"><table><thead><tr><th><strong>Annotation</strong></th><th><strong>Target</strong></th><th><strong>Interface to extend</strong></th><th><strong>Description</strong></th></tr></thead><tbody><tr><td>@JsonApiX</td><td>Class</td><td>None</td><td>Generates JSON:API wrappers and adapters for the target class</td></tr><tr><td>@HasOne</td><td>Class field</td><td>None</td><td>Indicates that a class field is a one-relationship</td></tr><tr><td>@HasMany</td><td>Class field</td><td>None</td><td>Indicates that a class field is a many-relationship</td></tr><tr><td>@JsonApiXLinks</td><td>Class</td><td>Links</td><td>Indicates that a target class should be used as a <strong>links</strong> model for its owner model</td></tr><tr><td>@JsonApiXMeta</td><td>Class</td><td>Meta</td><td>Indicates that a target class should be used as a <strong>meta</strong> model for its owner model</td></tr></tbody></table></figure>
		</div>
	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-307"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-305">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-306'
	>
	You’ll go a long way, library</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-310"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-308">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-309'
	>
	Making this library was a long and exciting journey for me and my colleagues. We had to overcome many challenges, and I can’t even count how many times I was busting my head for hours, even days, over some parsing issue.&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-313"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-311">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-312'
	>
	We give great thanks to the creators of <a href="https://github.com/Kotlin/kotlinx.serialization/blob/master/docs/serialization-guide.md">Kotlinx serialization</a> and <a href="https://square.github.io/kotlinpoet/">Kotlin poet</a>, because our work is heavily based on the features of those libraries. However, the journey is still not over, it’s rather just starting. And we have big plans for the future of the library.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-316"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-314">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-315'
	>
	Some of the most exciting upgrades we are planning to do are:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-319"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-317">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-318'
	>
	<li>Kotlin symbol processing support</li><li>Expanding the <code>JsonApiModel</code> API with more customizations and data</li><li>Custom error models</li><li>Many more&#8230;</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-322"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-320">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-321'
	>
	We welcome your contributions, so we’ve decided to <a href="https://github.com/infinum/kotlin-jsonapix">make this library open-source</a>! Feel free to peek through the code and open pull request.</p></div>	</div>
</div>
</div>		</div>
	</div><p>The post <a href="https://infinum.com/blog/a-kotlin-first-json-api-library-jsonapix/">A Kotlin-First JSON API Library – JsonApiX</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</content:encoded>
			</item>
		
	</channel>
</rss>