Notifications
Clear all
Topic starter 29/08/2025 11:43 pm
# Ruby on Rails REST API: Complete Guide Ruby on Rails is a powerful web framework that makes building RESTful APIs straightforward. Let me explain this step by step with practical examples. ## What is REST API? REST (Representational State Transfer) is an architectural style for designing networked applications. It uses HTTP methods to perform CRUD operations: - **GET**: Retrieve data - **POST**: Create new data - **PUT/PATCH**: Update existing data - **DELETE**: Remove data ## Setting Up Rails API Project ```bash # Install Rails gem install rails # Create a new API-only Rails application rails new my_api --api cd my_api # Generate a model (example: User) rails generate model User name:string email:string age:integer rails db:migrate ``` ## Basic Controller Structure ```ruby # app/controllers/users_controller.rb class UsersController < ApplicationController before_action :set_user, only: [:show, :update, :destroy] # GET /users def index @users = User.all render json: @users end # GET /users/1 def show render json: @user end # POST /users def create @user = User.new(user_params) if @user.save render json: @user, status: :created else render json: { errors: @user.errors }, status: :unprocessable_entity end end # PATCH/PUT /users/1 def update if @user.update(user_params) render json: @user else render json: { errors: @user.errors }, status: :unprocessable_entity end end # DELETE /users/1 def destroy @user.destroy head :no_content end private def set_user @user = User.find(params[:id]) end def user_params params.require(:user).permit(:name, :email, :age) end end ``` ## Routes Configuration ```ruby # config/routes.rb Rails.application.routes.draw do # RESTful routes for users resources :users # Or manually define routes # get '/users', to: 'users#index' # post '/users', to: 'users#create' # get '/users/:id', to: 'users#show' # patch '/users/:id', to: 'users#update' # put '/users/:id', to: 'users#update' # delete '/users/:id', to: 'users#destroy' end ``` ## Advanced Example: Blog API ```ruby # app/models/post.rb class Post < ApplicationRecord belongs_to :user has_many :comments, dependent: :destroy validates :title, presence: true validates :content, presence: true end # app/models/user.rb class User < ApplicationRecord has_many :posts, dependent: :destroy has_many :comments, dependent: :destroy validates :name, presence: true validates :email, presence: true, uniqueness: true end # app/controllers/posts_controller.rb class PostsController < ApplicationController before_action :set_post, only: [:show, :update, :destroy] before_action :authenticate_user!, except: [:index, :show] # GET /posts def index @posts = Post.includes(:user).all render json: @posts, include: [:user, :comments] end # GET /posts/1 def show render json: @post, include: [:user, :comments] end # POST /posts def create @post = current_user.posts.build(post_params) if @post.save render json: @post, status: :created else render json: { errors: @post.errors }, status: :unprocessable_entity end end # PATCH/PUT /posts/1 def update if @post.update(post_params) render json: @post else render json: { errors: @post.errors }, status: :unprocessable_entity end end # DELETE /posts/1 def destroy @post.destroy head :no_content end private def set_post @post = Post.find(params[:id]) end def post_params params.require(:post).permit(:title, :content, :published) end end ``` ## API Versioning Example ```ruby # config/routes.rb Rails.application.routes.draw do namespace :api do namespace :v1 do resources :users resources :posts end namespace :v2 do resources :users do member do patch :activate end end resources :posts end end end # Usage: # GET /api/v1/users # POST /api/v2/users ``` ## Error Handling and Response Formatting ```ruby # app/controllers/application_controller.rb class ApplicationController < ActionController::API rescue_from ActiveRecord::RecordNotFound, with: :not_found rescue_from ActiveRecord::RecordInvalid, with: :unprocessable_entity private def not_found(exception) render json: { error: exception.message }, status: :not_found end def unprocessable_entity(exception) render json: { errors: exception.record.errors }, status: :unprocessable_entity end end # Custom JSON response formatting class PostsController < ApplicationController def index @posts = Post.page(params[:page]).per(10) render json: { data: @posts, meta: { current_page: params[:page] || 1, per_page: 10, total: Post.count } } end end ``` ## Authentication Example (JWT) ```ruby # Gemfile gem 'jwt' gem 'bcrypt' # app/controllers/sessions_controller.rb class SessionsController < ApplicationController def create user = User.find_by(email: params[:email]) if user && user.authenticate(params[:password]) token = JWT.encode( { user_id: user.id, exp: 24.hours.from_now.to_i }, Rails.application.secret_key_base, 'HS256' ) render json: { token: token, user: user } else render json: { error: 'Invalid credentials' }, status: :unauthorized end end end # Authentication concern # app/controllers/concerns/authentication.rb module Authentication extend ActiveSupport::Concern private def authenticate_user! token = request.headers['Authorization']&.split(' ')&.last decoded_token = JWT.decode(token, Rails.application.secret_key_base, true, algorithm: 'HS256') user_id = decoded_token[0]['user_id'] @current_user = User.find(user_id) rescue JWT::DecodeError, ActiveRecord::RecordNotFound render json: { error: 'Unauthorized' }, status: :unauthorized end end ``` ## Testing Your API ```ruby # test/controllers/users_controller_test.rb require 'test_helper' class UsersControllerTest < ActionDispatch::IntegrationTest setup do @user = users(:one) end test "should get index" do get users_url, as: :json assert_response :success end test "should create user" do assert_difference('User.count') do post users_url, params: { user: { name: "John Doe", email: "john@example.com", age: 30 } }, as: :json end assert_response 201 end test "should show user" do get user_url(@user), as: :json assert_response :success end end ``` ## API Usage Examples ### Create a User (POST) ```bash curl -X POST http://localhost:3000/users \ -H "Content-Type: application/json" \ -d '{ "user": { "name": "John Doe", "email": "john@example.com", "age": 30 } }' ``` ### Get All Users (GET) ```bash curl http://localhost:3000/users ``` ### Update a User (PUT/PATCH) ```bash curl -X PATCH http://localhost:3000/users/1 \ -H "Content-Type: application/json" \ -d '{ "user": { "name": "John Smith", "age": 31 } }' ``` ### Delete a User (DELETE) ```bash curl -X DELETE http://localhost:3000/users/1 ``` ## Key Features of Rails API 1. **Built-in JSON Serialization**: Automatic conversion to JSON 2. **RESTful Routing**: Convention-based routing 3. **Strong Parameters**: Security against mass assignment 4. **ActiveRecord Integration**: Database operations 5. **Middleware Support**: Custom middleware for authentication, logging 6. **Testing Framework**: Built-in testing capabilities This setup provides a robust foundation for building REST APIs with Ruby on Rails, handling all the common CRUD operations efficiently.