Skip to content

Instantly share code, notes, and snippets.

@jdaviderb
Created June 23, 2025 14:15
Show Gist options
  • Save jdaviderb/840a2a4a00b880078bd4647a06009e60 to your computer and use it in GitHub Desktop.
Save jdaviderb/840a2a4a00b880078bd4647a06009e60 to your computer and use it in GitHub Desktop.
Internal API
---
description:
globs:
alwaysApply: true
---
# Internal API & CSRF for React
This document describes the conventions for creating internal API endpoints intended for use by frontend React components and the method for handling CSRF tokens.
---
## 1. Internal API Namespace (`/api/internal`)
* **Purpose:** Endpoints within the `api/internal` namespace are exclusively for asynchronous requests from frontend React components (e.g., saving forms, fetching specific UI data).
* **Routing:** Define these routes in `config/routes.rb` inside `namespace :api do namespace :internal do ... end end`.
* **Controllers:**
* Place controllers in `app/controllers/api/internal/`.
* They should inherit from `ApplicationController` (or another appropriate base API controller if one exists).
* **Authorization:** Always check for authentication (`before_action :authenticate_user!`) and **mandatorily** scope queries to resources belonging to the current user (`current_user.companies.find(...)` instead of `Company.find(...)`).
* **Responses:** Typically return JSON (`render json: ..., status: ...`). Handle errors and validations by returning appropriate statuses (e.g., `:ok`, `:not_found`, `:unprocessable_entity`) and a JSON body with errors.
* **Parameters:** Use Strong Parameters (`private def ..._params`) to define permitted attributes.
## 2. Handling CSRF Tokens in React
Rails uses CSRF tokens to protect against Cross-Site Request Forgery attacks. The frontend **must** send this token with every non-GET request (POST, PUT, PATCH, DELETE).
* **Prerequisite:** Ensure your main Rails layout (`app/views/layouts/application.html.erb`) includes the `<%= csrf_meta_tags %>` tag within the `<head>`.
* **Getting the Token in React:** Use JavaScript to read the token from the meta tag:
```javascript
const getCsrfToken = () => {
const token = document.querySelector('meta[name="csrf-token"]')?.content;
return token;
};
```
* **Sending the Token with `fetch`:** Include the token in the `X-CSRF-Token` header of your request:
```javascript
const csrfToken = getCsrfToken();
// ... check if token exists ...
fetch('/api/internal/...', {
method: 'POST', // or PUT, PATCH, DELETE
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'X-CSRF-Token': csrfToken // Here is the token
},
body: JSON.stringify({ /* your payload */ })
})
.then(response => /* ... */)
.catch(error => /* ... */);
```
---
**Always follow these conventions when interacting between React components and the Rails backend via the internal API.**
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment