Nouveau : Datasets open source gratuits disponibles !Decouvrir →
💎
Avance 30 min Rails

Microservices avec Rails

Pourquoi Microservices avec Rails ?

Au quotidien, en tant que développeur, vous êtes confronté à des projets de plus en plus complexes et distribués sur plusieurs systèmes et infrastructures. Les microservices ont été conçus pour aider à gérer ces projets en les décomposant en composants indépendants mais interconnectés. Cela permet d'améliorer la scalabilité, la maintenabilité et la flexibilité du code. Un cas d'usage concret est le développement d'une application e-commerce avec une base de données monolithique qui devient rapidement trop lourde à gérer.

Prerequis

Pour suivre ce tutoriel, vous aurez besoin des compétences suivantes :

  • Connaissance approfondie de Ruby et Rails
  • Expérience avec les bases de données SQL et NoSQL
  • Familiarité avec Docker pour le déploiement
  • Compétence en gestion des API RESTful

Vous devrez également installer les outils suivants :

  • Ruby 3.2.x (ou ultérieur)
  • Rails 7.0.x (ou ultérieur)
  • Node.js 16.x (pour les tâches backend et frontend si nécessaire)
  • PostgreSQL pour la base de données
  • Docker et Docker Compose

Concepts fondamentaux

Architecture des Microservices

Un microservice est un composant indépendant qui fait une seule chose bien. Chaque service a sa propre base de données, son propre langage de programmation et son propre déploiement.

## Un exemple d'un microservice simple avec Rails
class Task < ApplicationRecord
end

class TasksController < ApplicationController
  def index
    tasks = Task.all
    render json: tasks
  end

  def create
    task = Task.create!(task_params)
    render json: task, status: :created
  end

  private

  def task_params
    params.require(:task).permit(:title, :description)
  end
end

Communication Entre Microservices

Les microservices communiquent entre eux via des appels API RESTful ou gRPC. Cela permet une grande flexibilité et évolutivité.

## Un exemple d'appel API pour récupérer les tâches depuis un autre microservice
require 'net/http'

def get_tasks_from_another_service
  uri = URI('http://another-service/tasks')
  response = Net::HTTP.get(uri)
  JSON.parse(response)
end

## Utilisation dans un controller
class TasksController < ApplicationController
  def index
    tasks = get_tasks_from_another_service
    render json: tasks
  end
end

Gestion des États et Transactions

Chaque microservice doit gérer son propre état, ce qui signifie que les transactions complexes doivent être orchestrées entre les services.

## Un exemple d'orchestration de transactions entre plusieurs services
class OrderService < ApplicationService
  def call(order_params)
    begin
      order = Order.create!(order_params)
      PaymentService.new(order).call
      EmailService.new(order).call
      order.update(status: 'completed')
    rescue StandardError => e
      order.update(status: 'failed')
      raise e
    end
  end
end

Mise en pratique : Projet fil rouge

Nous allons créer un mini-projet complet : une application de gestion des tâches avec plusieurs microservices.

Étape 1 : Configuration du projet

Créez un nouveau répertoire et initialisez un nouveau projet Rails.

mkdir task-manager
cd task-manager
rails new backend --api --database=postgresql

Ajoutez Docker à votre projet pour faciliter le déploiement.

## docker-compose.yml
version: '3.8'
services:
  db:
    image: postgres
    environment:
      POSTGRES_DB: task_manager_development
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: password
    volumes:
      - ./db/postgresql:/var/lib/postgresql/data

  backend:
    build: .
    ports:
      - "3000:3000"
    volumes:
      - .:/app
    depends_on:
      - db

Étape 2 : Création des microservices

Créez trois microservices : tasks, users et auth.

rails g service TaskService
rails g model User email:string password_digest:string
rails g controller Users create show destroy
rails g controller Auth login

Étape 3 : Configuration des routes

Configurez les routes pour chaque microservice.

## config/routes.rb
Rails.application.routes.draw do
  namespace :tasks do
    resources :tasks, only: [:index, :create]
  end

  namespace :users do
    resources :users, only: [:create, :show, :destroy]
  end

  namespace :auth do
    post 'login', to: 'auth#login'
  end
end

Étape 4 : Implémentation des microservices

Implémentez les fonctionnalités pour chaque microservice.

## app/services/task_service.rb
class TaskService < ApplicationService
  def call(task_params)
    task = Task.create!(task_params)
    task
  end
end

## app/controllers/tasks_controller.rb
class TasksController < ApplicationController
  def index
    tasks = Task.all
    render json: tasks
  end

  def create
    task_service = TaskService.new
    task = task_service.call(task_params)
    render json: task, status: :created
  end

  private

  def task_params
    params.require(:task).permit(:title, :description)
  end
end

Étape 5 : Déploiement avec Docker

Déployez votre application avec Docker.

docker-compose up --build

Erreurs frequentes et debugging

Voici trois erreurs courantes et leurs solutions :

  1. Erreur : NoMethodError - undefined method `permit' for #Hash:0x00007f8b9c3a3a40

    # Code incorrect
    params.require(:task).permit(:title, :description)
    
    # Code correct
    task_params = params.require(:task).permit(:title, :description)
    
  2. Erreur : ActiveRecord::RecordInvalid - Validation failed: Title can't be blank

    # Code incorrect
    Task.create!(task_params)
    
    # Code correct
    if task.save
      render json: task, status: :created
    else
      render json: task.errors, status: :unprocessable_entity
    end
    
  3. Erreur : Net::HTTPServerException - 404 "Not Found"

    # Code incorrect
    uri = URI('http://another-service/tasks')
    response = Net::HTTP.get(uri)
    
    # Code correct
    uri = URI('http://localhost:3001/tasks') # Assurez-vous que le port est correct
    response = Net::HTTP.get(uri)
    

Pour aller plus loin

  1. Intégration Continu et Déploiement Automatisé (CI/CD)

    Utilisez des outils comme GitHub Actions ou GitLab CI pour automatiser les tests et le déploiement.

  2. Docker Compose pour la gestion des environnements

    Utilisez Docker Compose pour gérer les dépendances et les services en un seul fichier.

  3. Gestion des Sécurité et Authentification

    Ajoutez une couche de sécurité avec des mécanismes d'authentification et d'autorisation robustes.

Défi pratique : Créez un microservice pour gérer les commentaires des tâches et ajoutez-le à votre application.

Besoin d'aide sur Rails ?

Besoin d'aide sur un projet technique ? Decrivez-le pour des conseils personnalises.

Recevoir des conseils

Questions frequentes

Quelles sont les principales avantages des microservices avec Rails?
Les principaux avantages des microservices avec Rails incluent une meilleure scalabilité et la facilité d'extension individuelle de chaque service. Ils permettent également une plus grande modularité et une maintenance plus efficace.
Comment configurer le routage entre les différents services dans un architecture microservices avec Rails?
Pour configurer le routage entre les différents services, vous pouvez utiliser des outils tels que Nginx ou Apache en tant que reverse proxy. Vous devez également définir des endpoints spécifiques pour chaque service et gérer la communication entre eux via des API RESTful.
Quelles sont les meilleures pratiques pour le stockage de données dans une architecture microservices avec Rails?
Dans une architecture microservices, il est recommandé d'utiliser un stockage de données décentralisé. Chaque service devrait avoir sa propre base de données pour assurer la cohérence et l'indépendance des services. Pour les données partagées, vous pouvez utiliser des bases de données relationnelles ou non relationnelles comme MongoDB.

Pages liees

Chaque semaine, le meilleur de la tech francaise

Tendances, salaires, outils et opportunites — directement dans votre boite mail.

Gratuit. Desabonnement en un clic. Pas de spam.