Skip to content

Commit

Permalink
Added ✨️ Key Features of the Rails Application
Browse files Browse the repository at this point in the history
  • Loading branch information
hoshinotsuyoshi committed Oct 19, 2024
1 parent f8e17ee commit 2242768
Showing 1 changed file with 46 additions and 24 deletions.
70 changes: 46 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ $ tree -L 2
└── backend_schema.graphql
```

## Backend Development
## 💪 Backend Development

The backend is a Rails application running in API mode. Below are the key steps for setting up and running the backend:

Expand Down Expand Up @@ -68,7 +68,7 @@ The backend is a Rails application running in API mode. Below are the key steps
bundle exec rspec
```

## `graphql-schema` Directory and GraphQL Schema Code-First Approach
## 🧩 `graphql-schema` Directory and GraphQL Schema Code-First Approach

This project adopts a **Code-First** approach to defining GraphQL schemas using the `graphql-ruby` gem. Here’s how the backend and frontend integrate using GraphQL schemas:

Expand All @@ -88,7 +88,7 @@ This project adopts a **Code-First** approach to defining GraphQL schemas using

This process ensures that the types are correctly synchronized between the backend and frontend, facilitating type-safe GraphQL queries in the frontend.

## Frontend Development
## 💪 Frontend Development

The frontend is a Vite-powered React SPA, and Bun is used as the package manager. The primary build scripts are defined in `frontend/package.json`:

Expand All @@ -115,9 +115,10 @@ Key commands include:
- `bun run build:move`: Builds the frontend and moves the build artifacts into the Rails public directory.
- `bun run graphql-codegen`: Generates TypeScript types from the GraphQL schema.

## Deployment Process
## Deployment Process (🚧)

🚧 ~under construction~
> [!TIP]
> This section is still under construction.
The deployment process involves building the frontend, syncing the build artifacts to the Rails `public/` directory using `rsync`, and building the Docker image for the Rails API.

Expand All @@ -138,46 +139,67 @@ The deployment process involves building the frontend, syncing the build artifac
3. **Deploy**
Deploy the application using your preferred method (e.g., Docker Compose, Kubernetes, or any CI/CD pipeline).

## Key Features of the Rails Application
## ✨️ Key Features of the Rails Application

The Rails API serves as the backend for the SPA and manages authentication and routing for the client. Below are some technical highlights of the Rails setup.

### Routing and Static Assets
---

The Rails application serves the frontend SPA's assets for specific routes listed in `config/routes.rb`. These routes point to a static controller, which renders the `index.html` file generated by the frontend.
### 1. Authentication

#### Based on Rails 8's `bin/rails generate authentication`
This application leverages the Rails 8 authentication generator. Certain methods unnecessary for API mode have been commented out. During login mutations, filtered `request` information is exposed through `context`, allowing mutations in `app/graphql/mutations` to handle session data.

#### Secure Cookie-Based Sessions
This app uses `Set-Cookie` with `http-only` attributes for secure session management in a same-origin setup, avoiding the complexities of CORS, JWTs, or local storage solutions. Cookies are a well-established security measure and can help prevent some (albeit very limited) XSS vulnerabilities by ensuring that JavaScript cannot access session data.

#### API Mode and Cookie Management
The Rails API uses `ActionController::Cookies` to enable cookie-based sessions even in API mode, making client-side authentication seamless.

```ruby
class ApplicationController < ActionController::API
include ActionController::Cookies
end
```

---

### 2. Routing and Static Assets Management

Given that both backend and frontend must run on the same origin, care has been taken to avoid routing conflicts. The Rails API operates primarily through a single endpoint: `POST /graphql`. All other paths are reserved for frontend usage.

The `StaticController` serves the frontend's `index.html` for specified routes. Example routes:

```ruby
# config/routes.rb
to = "static#index"
[
"/login",
"/me",
"/onboarding/verify_email_address",
"/set_password",
"/signup",
].each { get _1, to: }
"/signup"
].each { get _1, to: "static#index" }
```

The `StaticController` reads the `index.html` from the `public` directory and serves it as the response for these routes:

```ruby
# app/controllers/static_controller.rb
class StaticController < ApplicationController
def index
response.headers['Content-Type'] = 'text/html'
render plain: Rails.public_path.join('index.html').read, layout: false
end
end
```

### Cookie Management
---

The Rails API uses `ActionController::Cookies` to manage cookie-based authentication and sessions, even though it runs in API mode. This allows for integration with client-side authentication flows.
### 3. Signup Flow

```ruby
class ApplicationController < ActionController::API
include ActionController::Cookies
end
```
The signup process follows a series of steps starting with the frontend collecting user details and making GraphQL mutations to create and authenticate users. Each step in the flow interacts with the backend API, which manages session creation and validation through GraphQL mutations.

---

### 4. System Test

Rails system tests are powered by Capybara and Puma. They use transactional database cleaning to ensure isolated tests, allowing easy testing of both frontend and backend interactions in an integrated environment.

---

This setup ensures that cookies are properly handled across the application, which is important for features such as authentication, user sessions, and cross-origin requests.
This version of the Key Features section fills in the missing details and organizes the content for clarity. Let me know if any further adjustments are needed!

0 comments on commit 2242768

Please sign in to comment.