Sobes.tech
Middle

Gdzie wyznaczasz granicę między rozwojem frontend a backend?

sobes.tech AI

Odpowiedź od AI

Granica znajduje się na poziomie API. Backend odpowiada za:

  • Logikę biznesową
  • Zarządzanie danymi (baza danych, cache)
  • Autoryzację i uwierzytelnianie (jeśli nie jest to wydzielone do osobnej usługi)
  • Udostępnianie danych i funkcji przez API (REST, GraphQL itp.)

Frontend odpowiada za:

  • Interfejs użytkownika (HTML, CSS)
  • Interakcję z użytkownikiem (JavaScript/Ruby z Hotwire itd.)
  • Konsumpcję danych i wywoływanie funkcji przez API backendu
  • Prezentację danych otrzymanych od backendu

W klasycznym podejściu backend generuje strony HTML, frontend jedynie dodaje interaktywność. W SPA (Single Page Application) granica jest bardziej wyraźna, ponieważ interakcja odbywa się wyłącznie przez API.

Przykład:

# app/controllers/api/users_controller.rb
# Backend: Odpowiada za pobranie użytkownika z bazy danych i formatowanie danych dla frontendu
class Api::UsersController < ApplicationController
  def show
    user = User.find(params[:id])
    render json: user.as_json(only: [:id, :name, :email])
  end
end
// app/javascript/packs/user_profile.js
// Frontend: Odpowiada za żądanie danych od backendu i ich wyświetlenie
document.addEventListener('DOMContentLoaded', () => {
  fetch(`/api/users/${userId}`) // userId pobierane na frontendzie
    .then(response => response.json())
    .then(data => {
      document.getElementById('user-name').innerText = data.name;
      document.getElementById('user-email').innerText = data.email;
    });
});

W podejściach hybrydowych, takich jak Hotwire, część logiki renderowania może być przesunięta na backend, ale interakcja nadal opiera się na przesyłaniu danych lub fragmentów HTML przez specyficzne protokoły (np. Turbo Streams).

# app/controllers/posts_controller.rb
# Backend: Renderuje HTML dla Turbo Stream
class PostsController < ApplicationController
  def create
    @post = Post.new(post_params)
    if @post.save
      render turbo_stream: turbo_stream.append(:posts, partial: 'posts/post', locals: { post: @post })
    else
      # Obsługa błędów
    end
  end

  private

  def post_params
    params.require(:post).permit(:body)
  end
end
<!-- _post.html.erb -->
<!-- Fragment HTML wysyłany do frontendu przez Turbo Stream -->
<div>
  <%= post.body %>
</div>

Podstawowa zasada: backend dostarcza dane i usługi, frontend je konsumuje i wizualizuje dla użytkownika.