Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Doc] Fix api implementation in Remix tutorial throws a decoding error when less than 10 records are returned #9448

Merged
merged 1 commit into from
Nov 15, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 10 additions & 8 deletions docs/Remix.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ title: "Remix Integration"

# Remix Integration

[Remix](https://remix.run/) is a Node.js framework for server-side-rendered React apps. But even if react-admin is designed to build Single-Page Applications, Remix and react-admin integrate seamlessly.
[Remix](https://remix.run/) is a Node.js framework for server-side-rendered React apps. But even if react-admin is designed to build Single-Page Applications, Remix and react-admin integrate seamlessly.

These instructions are targeting Remix v2.

Expand All @@ -23,7 +23,7 @@ This script will ask you for more details about your project. You can use the fo
- Initialize a new git repository? Choose Yes
- Install dependencies with npm? Choose Yes

The project structure should look like this:
The project structure should look like this:

![Remix v2 project structure](./img/remix-structure.png)

Expand Down Expand Up @@ -107,17 +107,17 @@ You can now start the app in `development` mode with `npm run dev`. The admin sh

## Adding an API

[Remix allows to serve an API](https://remix.run/docs/en/main/guides/api-routes) from the same server. You *could* use this to build a CRUD API by hand. However, we consider that building a CRUD API on top of a relational database is a solved problem and that developers shouldn't spend time reimplementing it.
[Remix allows to serve an API](https://remix.run/docs/en/main/guides/api-routes) from the same server. You *could* use this to build a CRUD API by hand. However, we consider that building a CRUD API on top of a relational database is a solved problem and that developers shouldn't spend time reimplementing it.

For instance, if you store your data in a [PostgreSQL](https://www.postgresql.org/) database, you can use [PostgREST](https://postgrest.org/en/stable/) to expose the data as a REST API with zero configuration. Even better, you can use a Software-as-a-Service like [Supabase](https://supabase.com/) to do that for you.
For instance, if you store your data in a [PostgreSQL](https://www.postgresql.org/) database, you can use [PostgREST](https://postgrest.org/en/stable/) to expose the data as a REST API with zero configuration. Even better, you can use a Software-as-a-Service like [Supabase](https://supabase.com/) to do that for you.

In such cases, the Remix API can only serve as a Proxy to authenticate client queries and pass them down to Supabase.
In such cases, the Remix API can only serve as a Proxy to authenticate client queries and pass them down to Supabase.

Let's see an example in practice.
Let's see an example in practice.

First, create a Supabase REST API and its associated PostgreSQL database directly on the [Supabase website](https://app.supabase.com/) (it's free for tests and low usage). Once the setup is finished, use the Supabase manager to add the following tables:

- `posts` with fields: `id`, `title`, and `body`
- `posts` with fields: `id`, `title`, and `body`
- `comments` with fields: `id`, `name`, `body`, and `postId` (a foreign key to the `posts.id` field)

You can populate these tables via the Supabse UI if you want. Supabase exposes a REST API at `https://YOUR_INSTANCE.supabase.co/rest/v1`.
Expand Down Expand Up @@ -146,6 +146,7 @@ export const loader = ({ request }: LoaderFunctionArgs) => {
headers: {
prefer: request.headers.get("prefer") ?? "",
accept: request.headers.get("accept") ?? "application/json",
"Accept-Encoding": "",
apiKey: `${process.env.SUPABASE_SERVICE_ROLE}`,
Authorization: `Bearer ${process.env.SUPABASE_SERVICE_ROLE}`,
},
Expand All @@ -162,6 +163,7 @@ export const action = ({ request }: ActionFunctionArgs) => {
headers: {
prefer: request.headers.get("prefer") ?? "",
accept: request.headers.get("accept") ?? "application/json",
"Accept-Encoding": "",
apiKey: `${process.env.SUPABASE_SERVICE_ROLE}`,
Authorization: `Bearer ${process.env.SUPABASE_SERVICE_ROLE}`,
},
Expand Down Expand Up @@ -231,4 +233,4 @@ export default function App() {

That's it! Now Remix both renders the admin app and serves as a proxy to the Supabase API. You can test the app by visiting `http://localhost:3000/admin`, and the API Proxy by visiting `http://localhost:3000/admin/api/posts`.

Note that the Supabase credentials never leave the server. It's up to you to add your own authentication to the API proxy.
Note that the Supabase credentials never leave the server. It's up to you to add your own authentication to the API proxy.
Loading