Custom API Content
Rendering content from an API remains one of the most popular use cases of the Vyuh Framework. This is expected as most real-world apps will fetch data from an API and render it as per the brand guidelines.
In this guide, we will see how to integrate a third-party API and render it as per our needs.
1. Identifying a Third-Party API
After searching the internet for free API resources, we decided to go with the one at DummyJSON 🔗. This resource gives a variety of APIs for products, carts, recipes, todos, etc.
The API for Products is what we decided to use for this example. It has a rich schema for its responses and good query parameters around which we could model our API Configuration.
There are two endpoints for products that we can use:
- Products list 🔗
(
https://dummyjson.com/products
): shows a list of products with query parameters to control thelimit
andskip
. - Products search 🔗
(
https://dummyjson.com/products/search?q=<search-text>
): allows searching for products with some search terms (using theq
parameter). It also supports thelimit
andskip
query parameters.
2. API Configuration schema for the CMS
Based on the parameters we saw earlier, we have come up with a schema that can
be configured from the CMS. It allows changing the limit
, skip
and
searchText
parameters. We have also exposed the two types of product endpoints
with a simple type
enum.
Here is the Sanity schema, with a few parts elided for brevity.
To ensure this shows up in our CMS, we need to add it to the
FeatureDescriptor
, like so.
Now our API configuration shows up on the CMS and we can configure it as we need.
3. API Configuration on the Flutter side
As you may already know, the CMS counterpart on the Flutter side has an
equivalent FeatureDescriptor
that includes the Dart TypeDescriptor
which
can handle fetching and rendering this API Content.
This is done by extending the ApiConfiguration<T>
abstract class. Here we
define the schemaType
, matching the CMS schema, and override its two methods:
invoke(BuildContext context)
: invokes the API and fetches the content (which you can wrap in type<T>
). This is then passed to thebuild
method.build(BuildContext context, T? data)
: Renders the data as per the Design System. It is possible to receive null, which could be because of lack of data or an error. The type<T>
, which represents the response from the API can be defined by you. You can add your exception, if any, or just return plain data. If you want to show more details about the API response, you can create a more complex type to capture it.
In our case, we chose to use a simple ProductList
type that is a direct mirror
of the response we get from the DummyJSON API. Thus, our Dart equivalent of the
API configuration looks like so:
Note that the model types: ProductList
, Product
and
DummyJsonProductApiType
are defined in a separate file (model.dart
). These
are the Dart objects that map to the JSON response from the API. Also notice
the use of the vyuh.network
plugin for invoking the API. This is the
recommended way of invoking APIs in Vyuh. The plugin wraps the HttpClient
from
the standard library.
The use of the static fields for schemaName
and typeDescriptor
are just
conventions that we have found to be very useful. It keeps the details neatly
tucked in the class and makes it easy to include it in the FeatureDescriptor
,
as seen below:
Notice the use of the APIContentDescriptor
where we specify the
typeDescriptor
for the Dummy JSON API configuration. Later on, if we plan to
add more API configurations, we could include them as well in the
configurations
array for the APIContentDescriptor
.
4. API content in action
We can now include the API Content block on the CMS and configure it with the DummyJSON API.
On the Flutter side, if we do a hot-reload and load the page which has this content block, we can see it live. We have done some simple styling to render the list of products with custom ListContainer and ProductTile widgets.
Summary
Vyuh has rich provision to integrate custom API endpoints and render their
responses. To configure it on the CMS, we define a custom schema with the
APIContentDescriptor
.
There is a similar task on the Flutter side, where we take care of the
implementation details of invoking the API and rendering it. This is done with
the APIContentDescriptor
where we include the typeDescriptor
for this
configuration.
Together we now have a powerful, configurable API Content block that can be changed dynamically from the CMS.