2.4. Inferencer for CRUD Pages
This post discusses the refine's Inferencer tool which works behind a number of Inferencer components to generate code for CRUD pages automatically. We examine the preview of the rendered pages in our React admin panel app and get familiar with the Inferencer's powerful ability to generate code just by inferring a valid resource action from the current browser URL.
The Inferencer Components
If we look inside src/pages
directory, we can see that pages related to blog_posts
and categories
have been already generated for us. When we investigate the pages, we see that there's no code for the UI elements for these pages.
For example, list
page for blog_posts
look like this:
import { IResourceComponentsProps } from "@refinedev/core";
import { MuiListInferencer } from "@refinedev/inferencer/mui";
export const BlogPostList: React.FC<IResourceComponentsProps> = () => {
return <MuiListInferencer />;
};
We can see that only a <MuiListInferencer />
element is returned from the <BlogPostList />
. And that's it.
Similarly, the <BlogPostCreate />
component returns only a <MuiCreateInferencer />
, the <BlogPostShow />
component has a <MuiShowInferencer />
and so on. In refine, every CRUD action has an Inferencer variant in the UI frameworks it supports.
The above discussed MUI Inferencer elements, in this case each representing an Inferencer tailored for producing Material UI components, are generating the code for the pages we have in our admin panel app.
refine has Inferencers for other UI frameworks it supports as well, such as Ant Design, Mantine and Chakra UI.
What is the Inferencer ?
The Inferencer is a powerful tool in the refine ecosystem that makes the app quickly implement CRUD (create, read, update, delete) pages for its data models. It analyzes the app's data models based on the resources schema and automatically generates the code for pages with required forms and tables for CRUD operations.
The UI elements of a page are determined based on an initial API polling of the resource
and action of the page inferred from the current URL of the browser and validated against the resources
definitions.
The resources
prop is explained in detail in Unit 3.2. For now, we can assume that a resource is a collection of data available in the backend API used in the app.
Why Use an Inferencer ?
There are several benefits to using an Inferencer:
The goal of the Inferencer is to scaffold out page views for the app's resources with minimal code. This saves significant amount of time and effort, especially on large projects with many resources.
Code generated by Inferencer is also easy to customize. Instead of a blank view, the auto-generated code gives us a stable starting point to tweak and build more features on its top. This allows developers to iterate faster and get the project up and running quickly.
Using Inferencer can also help lower bugs, as the code generated for CRUD pages is functional by default. This increases development efficiency and productivity.
Overall, using Inferencer speeds up development by reducing manual coding time and potential bugs. It helps ensure that CRUD pages are consistent and adhere to best practices, giving developers room to focus on more complex app logic instead.
Using Inferencer, however, is not suitable in production. Therefore, they are typically used only in development.
Learn Inferencer
You can Learn more about how Inferencer works and how to use it with Material UI from the documentation.
Inferencer with refine App Scaffolder
Inferencer variants comes baked with the admin panel app that we initialized with refine App Scaffolder. They are provided by the @refinedev/inferencer/mui
package that avails the Material UI Inferencer variants for each action of a resource.
For example, when we examine the page components for the actions of blog_posts
resources at src/pages/blog-posts/
directory, we can see each variant being used to generate code for its respective action. In other words,
<MuiListInferencer />
is used to implement page forlist
action<MuiCreateInferencer />
is used to implement page forcreate
action<MuiEditInferencer />
is used to implement page foredit
action<MuiShowInference />
is used to implement page forshow
action
In the below sections, we preview the pages created and peek into the actual code generated by these Inferencers.
Previewing Auto-generated Pages
In the sections below we navigate through each CRUD page rendered. However, before we start previewing, let's understand the API that we are using in this tutorial.
We are using the Simple REST API hosted here. This is a mock JSON API created by refine and is used for demo purposes. It is a simple REST API that contains some resources like blog_posts
, categories
, etc.
How refine apps communicate with the API via the dataProvider
is explained in Unit 3.2.
We are covering pages for only blog_posts
resource since the same actions are implemented for categories
.
List Page
The blog_posts
list
page is available at the default route, /
of the app. That is, at http://localhost:5173.
The code for this list
page is generated by Inferencer as per the <MuiListInferencer />
component:
import { IResourceComponentsProps } from "@refinedev/core";
import { MuiListInferencer } from "@refinedev/inferencer/mui";
export const BlogPostList: React.FC<IResourceComponentsProps> = () => {
return <MuiListInferencer />;
};
When you navigate to http://localhost:5173
, refine redirects to the first resource's list page registered to <Refine />
component, i.e. to the list
page of blog_posts
at http://localhost:5173/blog-posts
The preview of the blog post list page looks so:
We can see a tabular presentation which did not need to be coded by us. Feel free to play with sorting the table content with respect to a given column.
For example, you can use the table menu to explore options for sorting and filtering the presented data:
All these components were appropriately figured out and coded by the Inferencer. We inspect and analyze the generated code in Unit 4.1.
Create Page
The preview for the create
page is available at /blog-posts/create
, i.e. at http://localhost:5173/blog-posts/create.
Navigate to there or click the Create
button in the blog post list page.
The code for this create
page is generated by Inferencer as per <MuiCreateInferencer />
component:
import { IResourceComponentsProps } from "@refinedev/core";
import { MuiCreateInferencer } from "@refinedev/inferencer/mui";
export const BlogPostCreate: React.FC<IResourceComponentsProps> = () => {
return <MuiCreateInferencer />;
};
The preview of the blog post create page looks like this:
We can see a form with the fields to create a blog post. All these form fields and their resource schema, along with the usage of the appropriate components and data hooks were figured out and coded by the Inferencer.
We examine the generated code in Unit 4.4.
Edit Page
The preview for the edit
page is available at /blog-posts/edit/:id
, i.e. at http://localhost:5173/blog-posts/edit/:id:
The code for this edit
page was generated by Inferencer as per <MuiEditInferencer />
component:
import { IResourceComponentsProps } from "@refinedev/core";
import { MuiEditInferencer } from "@refinedev/inferencer/mui";
const BlogPostEdit: React.FC<IResourceComponentsProps> = () => {
return <MuiEditInferencer />;
};
The preview for the blog posts edit page looks like this:
We can see a form with fields to edit a blog post. Notice that all the field data get filled as soon as the page loads, indicating the use of data hooks and placing of appropriate Material UI components by the Inferencer.
We examine and discuss the generated code in Unit 4.2.
Show Page
The preview for the show
page is available at /blog-posts/show/:id
, i.e. at http://localhost:5173/blog-posts/show/show/:id or click the eye (Show) icon on the list page.
The code for this show
page was also generated by Inferencer, as per <MuiShowInferencer />
component:
We can see a page that shows a blog post with relevant details presented. The Inferencer, once again, figured out the resource schema of the data fetched with appropriate hooks and then placed the necessary Material UI components to the blog posts show page. We inspect and elaborate on the generated code in Unit 4.3.
Recap
The Inferencer generated CRUD pages by placing appropriate components and hooks in our React admin panel app after inferring a valid resource action from the current browser URL. These components and hooks under the hood operate inside different contexts or refine layers, defined by a set of refine providers such as dataProvider
and authProvider
.
The providers are fundamental to the operations of a refine app, first have to be configured and then passed to the <Refine />
component. In Unit 3, we cover these concepts with more discussion on dataProvider
, resources
and authProvider
props .