Except as otherwise stated in the Extend Knowledge Content site policy, the content on this page is licensed under the Creative Commons Attribution 4.0 Licence, and any code samples that appear on this page are licensed under the Apache 2.0 Licence, unless any code sample forms part of the Fluent Order Management Platform code. Neither of these licences apply to any content on any other page that can be reached via a link on this page unless otherwise specified on that other page. If you wish to use any of the Extend KnowledgeContent, you must do so in compliance with the licenses referred to above and the Extend Knowledge Content site policy, including attribution in the manner set out on this page.
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 GraphQL. The Fluent Platform includes a number of REST APIs, not available via GraphQL. 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 article 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
Since the standard Components accept datasources from the page query defined in the manifest, 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 manifest.
Scenario
Imagine you needed to provide an enhanced Activity Viewer, Webhooks Dashboard, or display information from the Event 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
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 manifest 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 manifest.Example manifest usage:
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 manifest.Now you can create the Component:
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:
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:
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 event that the API call is still executing, it is helpful to show the `Loading` component as helpful feedback for the user.In the event that the API returns 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 returns 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){2case"ok":3return<ChildrendataOverride={decorateQueryResult(response.result)}/>;45case"loading":6return<Loading/>;78default:9// includes "error"10console.error(11`Could not retrieve data from REST API: ${JSON.stringify(endPointWithProps)}\n Response: ${JSON.stringify(response,null,2)}`12);13return<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'`.
Tip
The `decorateQueryResult` function provided by the Component SDK enables the `byName`attribute accessor capability documented here.
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 manifest:
1{2"type":"url",3"src":"http://localhost:3001"4}
Since we’ll try this using the Event 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:
As you can see above, we’re configuring the `devrel.provider.rest` component to call the Event API with filter parameters to return only FAILED OrderOrchestration 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
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 Event Dashboards, Webhook 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 Rule Library.Combining this with standard GraphQL page queries, you can build richer domain or entity 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.
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.
Get the Full Source Code
Check out the full source code for this articlehere.