View classes in the API application are the biggest change to what you are used to doing in Joomla components.
All these years you have been writing components with a backend and frontend part. Most of the time you had a View class whose purpose was to generate HTML using view templates. Quite rarely some of you may have used a raw, XML or JSON view to output something else such as INI data, binary data (e.g. an image), and XML document or a JSON string. In all cases you were more or less constructing the data as a string and had your view return that string.
The API application views extend from
\Joomla\CMS\MVC\View\JsonApiView
which is a
special version of the good, old, reliable
\Joomla\CMS\MVC\View\JsonView
we had for years.
Its biggest difference is that you are no longer constructing and
return a string. Instead, you have a
\Joomla\CMS\Serializer\JoomlaSerializer
object
which figures out how to best convert your raw data to a JSON
representation. Moreover, you have separate methods for displaying a
single item (displayItem
) versus displaying a
list of items (displayList
).
The two methods need to know which of the fields returned by
your Model's getItem
and
getItems
methods, respectively, needs to be
output in the JSON document. You can do that by setting two string
array properties, $fieldsToRenderItem and
$fieldsToRenderList. The former lists all the
fields to be output when rendering a single item view (the
displayItem
method in the Controller) and the
latter lists all the fields to be output when rendering a view which
returns multiple items (the displayList
method
in the Controller).
![]() | Note |
---|---|
At first glance this sounds tedious, if not pointless, but it
does make sense when you start thinking about it. When listing tree
entries, like menu items, there is no point in outputting the
internal fields |
The hidden gem of the API view is another string array property,
$relationship. In that view you list all the
field names returned by your model which refer to related
data. Now, this is where things get interesting! A contact
has, for example, a user ID. The user ID tells us nothing. However,
the user ID is not a standalone thing; it's a reference to the
related user record. Therefore listing
user_id
in the $relationship
array
tells the JsonapiView
that it needs to fetch
that related record and include it in the returned JSON document along
with information which tells the consumer that this embedded JSON
document refers to that user_id
— and the URL to
use to get more information about it.
There is a catch to using relations: you need a custom
Serializer object which extends
\Joomla\CMS\Serializer\JoomlaSerializer
and
adds one public method named after each relationship field. Each
method returns a \Tobscure\JsonApi\Relationship
object which is used to output the relationship links in the JSON
document. The custom Serialiser object is assigned to the
serializer property of your JsonapiView in its
constructor. This sounds very abstract and confusing; it's best if you
observe it in real world code. I recommend taking a look at Joomla's
own
\Joomla\Component\Content\Api\View\Articles\JsonapiView
and
\Joomla\Component\Content\Api\Serializer\ContentSerializer
to get a feeling of how you can add relationships in JSON API
views.