Display REST API Data in Standard Library Components
Author:
Lesley Dean
Changed on:
8 July 2024
Key Points
- For Frontend (React) Developers who are familiar with using the Fluent OMX Component SDK
- Build a REST API Data Provider Component to enable the standard Component Library to render data from the Fluent Platform REST APIs
- Learn how to override the data provided to components
- Learn how to support template value props for dynamic input
- Learn how to decorate the query results for enabling
`byName`
attributes access in the manifest
Steps
Introduction
Overview
The Fluent UX Framework provides a Component Library for quickly configuring Fluent web apps.
Currently these Components receive data from the Page Query, which is . The Fluent Platform includes a number of REST APIs, not available via . This means that the standard Components can't display REST based data.
Imagine if you could easily use the UX Framework Component Library to build and extend screens with data from these APIs?
This will guide you through implementing a custom data provider component that makes it possible to display REST based data in the standard UX Framework Component Library.
Problem Statement & Scenario
Problem Statement
Since the standard Components accept datasources from the page query defined in the , the only way to display data from REST APIs is to write custom components using the Component SDK.
This would need to be done for each component where a custom data source is required, and potentially adds significant effort to implementation.
While the Component SDK provides the tools to achieve this, it would be ideal if we could reuse the existing component library, and configure an alternate data source in the .
Scenario
Imagine you needed to provide an enhanced Activity Viewer, Webhooks Dashboard, or display information from the API on your Orders Dashboard.
Additionally, you need to achieve this while maintaining a consistent look, feel, and configuration experience, while minimising the total cost of custom code components?
What if this could be achieved with one simple custom component, and work for all components in the library?

An example Dashboard using Event API as a datasource for the standard Dashboard Tile Component
Solution
Approach
Following the pattern of the default page component, let's decouple the data fetching and display logic so that we can use the standard cards, lists, and other library components.
Let's write a simple custom component as a configurable data provider for nested components to use.
In this approach, the data provider component could accept an `endpoint`
, and some additional `props`
to configure the request or body parameters. Internally, it would execute the REST Call, and return a data source for the nested components defined within the .
Example usage:
1{
2 "component": "devrel.provider.rest",
3 "props": {
4 "endpoint": "api/v4.1/event",
5 "props": {
6 "context.entityType": "ORDER",
7 "eventType": "ORCHESTRATION",
8 "eventStatus": "FAILED",
9 "from": "{{dateStringFormatter (dateAdd hours=-24) 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]' true}}"
10 }
11 },
12 "descendants": [
13 /* display components here... */
14 ]
15}
Implementation Steps
Step 1: Create a custom Data Provider Component
Using the Component SDK, create a new file in the components folder called `RestProvider.tsx`
.
Create a new Interface to accept the RestProviderProps:
1export interface RestProviderProps {
2 data: any;
3 endpoint: string;
4 props: Record<string, string>;
5}
The `data`
field will automatically be provided by the UX Framework and contain the Page Query Data.
The `endpoint`
and `props`
fields will be configured in the .
Now you can create the Component:
1export const RestProvider: FC<RestProviderProps> = ({
2 data,
3 endpoint,
4 props,
5 }) => {
6 // TODO: Implementation Code here...
7};
A you can see, we make use of a React Function Component (`FC`
), which you should import from `react`
.
Step 2: Render Props and Build the REST endpoint with props
The UX Framework provides the ability to pass page query and URL parameters into the props values. The best way to handle this is to support template strings as props, which then need to be “rendered”. The TemplateRegistry provides a render function to do this for you. So all we need to do is loop through the provided props, and call the render function.
Let’s create a separate function in the same file for this:
1const getRenderedProps = (props: Record<string, string>, data: any) => {
2 return Object.fromEntries(
3 Object.entries(props).map(([key, value]) => [
4 key,
5 TemplateRegistry.render(value, data)
6 ])
7 );
8};
You will need to import the TemplateRegistry from `mystique/registry/TemplateRegistry`
.
Now we can use this function in our Component implementation and build the endpoint:
1 const [endPointWithProps] = useState(
2 () => `${endpoint}?${new URLSearchParams(getRenderedProps(props, data))}`
3 );
The `useState`
hook should be imported from `react`
.
As you can see from the code above, we will keep state of the provided parameters, so as not to re-render the component unnecessarily if the props values are changing all the time. This is relevant to our example use case, where we will be providing a “Last 24 Hours” date range to the request, and this would be changing every millisecond, triggering a re-render unnecessarily.
Step 3: Call the REST API and return the result to the child components
The Component SDK provides a `useRest`
hook to call the Fluent Platform REST APIs:
1const response = useRest(endPointWithProps);
Import the `useRest`
hook from `mystique/hooks/useRest`
.
The `response`
will contain 2 simple fields, `status`
and `result`
. We can use the `status`
to determine what to return using a switch statement.
In the that the API call is still executing, it is helpful to show the `Loading`
component as helpful feedback for the user.
In the that the API an error, we can log the rendered request to the console to help developers debug the problem, and depending on the use case present something else to the UI.
When the API successfully, the status will be `ok`
, and the `result`
object will be populated with the REST response payload. In this case, we can then return the `Children`
component, and override the data source. The result of the REST query now becomes the `data`
value injected into each descendant component, so any component designed to display information can be used to show it.
Let’s implement a simple switch statement to render feedback to the user:
1switch (response.status) {
2 case "ok":
3 return <Children dataOverride={decorateQueryResult(response.result)} />;
4
5 case "loading":
6 return <Loading />;
7
8 default:
9 // includes "error"
10 console.error(
11 `Could not retrieve data from REST API: ${JSON.stringify(endPointWithProps)}\n Response: ${JSON.stringify(response, null, 2)}`
12 );
13 return <div>Error occurred loading data from REST API</div>;
14}
Import `Children`
from `mystique/components/Children`
, `Loading`
from `mystique/components/Loading`
, and `decorateQueryResult`
from `'../../../lib/mystique-export'`
.
Step 4: Register the Component and try it out
In the `index.tsx`
, register the component:
1ComponentRegistry.register(["devrel.provider.rest"], RestProvider, {category: "content"});
You'll need to import `RestProvider`
from `'./components/providers/RestProvider'`
.
Start your local server by running `yarn start`
, and add your local server to the plugins configuration of your Fluent OMS webapp :
1{
2 "type": "url",
3 "src": "http://localhost:3001"
4}
Since we’ll try this using the API, let’s use the Insights section of the Fluent OMS webapp. If you haven’t already, you will need to override the default Insights fragment for Fluent OMS.
Let’s add a new Page to the Insights fragment, and try out the component:
1{
2 "type": "page",
3 "path": "/devrel-events-dashboard",
4 "nav": {
5 "label": "DevRel Events Dashboard",
6 "icon": "MdEvent"
7 },
8 "component": "fc.page",
9 "props": {
10 "title": "DevRel Events Dashboard - Updated on: {{dateStringFormatter (dateAdd)}}"
11 },
12 "descendants": []
13}
To test the REST Provider Component, we’ll use the standard `fc.dashboard.threshold`
component from the standard Component Library. This will need to be nested as a child descendant of the RestProvider component:
1{
2 "component": "devrel.provider.rest",
3 "props": {
4 "endpoint": "api/v4.1/event",
5 "props": {
6 "context.entityType": "ORDER",
7 "eventType": "ORCHESTRATION",
8 "eventStatus": "FAILED",
9 "from": "{{dateStringFormatter (dateAdd hours=-24) 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]' true}}"
10 }
11 },
12 "descendants": [
13 {
14 "component": "fc.dashboard.threshold",
15 "props": {
16 "label": "Failed",
17 "value": "{{ results.length }}",
18 "thresholdLow": 1,
19 "thresholdHigh": 10,
20 "link": "#/events?context.entityType=ORDER&eventType=ORCHESTRATION&eventStatus=FAILED&from={{dateStringFormatter (dateAdd hours=-24) 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]' true}}"
21 }
22 }
23 ]
24}
As you can see above, we’re configuring the `devrel.provider.rest`
component to call the API with filter parameters to return only FAILED Events for the last 24 hours, but remember you could pass in dynamic values from a page query result based on the use case.

A standard Dashboard Tile Component displaying failed Order Orchestration Events
What else can you do?
The Art of the Possible...
The applications for this include composing various UI capabilities for the data exposed by the Fluent Platform APIs. You can build out Dashboards, Dashboards (coming soon), enhanced Activity views for entities, display execution paths and status transition information, or even display a List of Workflows and a detailed Library.
Combining this with standard page queries, you can build richer domain or based dashboards, activity views, etc.
You can make further enhancements to this component, such as rendering the Loading and Error responses in a card.
Additionally, you can swap out the `useRest`
hook with the `getRest`
promise to query data from any other external API.
Finally, while this component won't allow support for all child component features, such as list paging and filtering, you can combine this with a custom List wrapper component, to enable these capabilities.
The REST API Data Provider demonstrates how quick and easy it is to extend the UX Framework, and maximise reuse of standard library components for REST based data.
Conclusion
Wrapping up
As you can see, this little custom component makes it super simple to enable presentation of REST API based data with the standard Component Library.