Consuming a Rails API with a NextJs client

Raphael Almeida Araújo
4 min readNov 28, 2022
NextJs on Rails

tl;dr; Previously here, I wrote about how to write a modern web application using Rails as a full-stack framework just writing HTML and Vanilla Javascript. Now we will go ahead creating a React client App using NextJs.

The existing API has the following endpoints:

GET /api/kit/products(.:format)
POST /api/kit/products(.:format)
GET /api/kit/products/:id(.:format)
PATCH /api/kit/products/:id(.:format)
PUT /api/kit/products/:id(.:format)
DELETE /api/kit/products/:id(.:format)

In the new project, we have the same screen as before:

In addition, the screen lists all products, a form filter, and a form to create and manage the products.

We have a lot of customized components:

src/components/
├── Form
│ ├── Actions.tsx
│ ├── Input.tsx
│ └── index.tsx
├── Layout
│ ├── Page.tsx
│ ├── Sidebar.tsx
│ └── index.tsx
├── Loading.tsx
├── LoadingOverlay.tsx
├── Notification.tsx
├── Products
│ ├── Form.tsx
│ └── Sidebar.tsx
└── SearchList
├── Form.tsx
├── ListItem.tsx
└── index.tsx

But our pages are simple and short. For example, take a look at the products page code:

Highlights

NextJs is just a choice, not a requirement
The API made using Ruby on Rails is completely independent of the NextJs client application developed with NextJs. You could use any RESTfull client application to consume the existing API.
In my project, I am using the NextJs project as a subfolder of my Rails repository, but you could put it anywhere.

Why NextJs
I already worked with React Router and React Navigation, but when I knew the Next/Router and all related features, as the Next/Link, I loved it. We can use partial load and caches. Get more info here.

Conventions
You can create your own convention for your own projects. But, in my opinion, it is beneficial to use a convention that is popular and validated in production by many other developers. Like Ruby on Rails, NextJs gives you a directory structure, core resources (link, routes, image, etc.), and rich documentation.

SSR (Server Side Rendering)
After creating a few projects using SPA, it doesn’t seem to me to be a good choice for big projects. So, for now, I am using SSR with NextJs. The main use of SSR is to improve the SEO, but I like this approach to offer a better UX.

React Query is the link between the Rails and NextJs
Working together with Axios (my code), it is a great option to consume the REST API (and GraphQL). You have the access to: isLoading, isError, data, error, and others. It is a very easy way to load data and rescue errors.

React Context
I don’t like https://react-redux.js.org/, it brings complexity to the project that I don’t think is a good thing. But we can use the React Context and React Reducer to offer storage and events to manage the states of the application. You can see it on the project here https://github.com/raphox/rails-7-fullstack/tree/nextjs/frontend/src/contexts/products.
In my code, I am using a context to share the state between different components on the same screen. The Form component is able to update the product item in the sidebar list.
The React Query also uses a context and we can exchange states between them. After updating a product, we can trigger changes to the product list.

React components with namespace
It is something that I learned recently. I used it in my project to offer a way to override children of some components and prevent setting many properties through the parent. Like in the following code:

https://github.com/raphox/rails-7-fullstack/blob/nextjs/frontend/src/components/Products/Sidebar.tsx#L27-L42

In the previous code, we have the namespace SidebarPrimitive with nested Root, Header, and List components. I am using the Root component to wrap the content and I am passing the props to the respected child.

Tailwind
There are controversies related to it, but trust me, create a project using it and make sure that you don’t like or love it.

Dependencies:

The project

External references:

--

--