0Pricing
Elixir & Phoenix: Scalable Backend Development · درس

تطبيق نقاط نهاية API وتسلسل البيانات

ابنوا نقاط نهاية API، وتعاملوا مع أجسام الطلبات والاستجابات، وقوموا بتسلسل البيانات بكفاءة لاستخدام العملاء.

تطبيق نقاط نهاية API وتسلسل البيانات درس مجاني في Elixir & Phoenix: Scalable Backend Development على CoddyKit. هذا هو الدرس 2 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Elixir & Phoenix: Scalable Backend Development، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Elixir & Phoenix: Scalable Backend Development 4 دروس في المجموع.

بعض أجزاء هذا الدرس لم تُترجم بعد وتظهر باللغة الإنجليزية.

API Endpoints: The Basics

Welcome! In this lesson, we'll build API endpoints in Phoenix. An API endpoint is a specific URL that an API client can access to perform an action or retrieve data.

Think of it as a digital address for a specific resource, like /api/products or /api/users/123. Each endpoint usually corresponds to an action (e.g., get all products, create a new user).

Scaffolding an API Resource

Phoenix provides a handy generator to quickly set up a RESTful API resource. We'll use mix phx.gen.json to create a Product resource.

This command generates:

  • A router entry
  • A controller (e.g., ProductController)
  • An Ecto schema (e.g., Product)
  • A view (e.g., ProductView) for JSON serialization

mix phx.gen.json Products Product products name:string description:text price:decimal

The API Controller: Listing & Showing

After generating, let's look at a basic API controller. The index action handles GET /products to list all products. The show action handles GET /products/:id to display a single product.

Phoenix controllers use conn (the connection) to manage requests and responses. We fetch data and then render it as JSON.

defmodule MyAppWeb.ProductController do
  use MyAppWeb, :controller
  alias MyApp.Products
  alias MyApp.Products.Product

  action_fallback MyAppWeb.FallbackController

  def index(conn, _params) do
    products = Products.list_products()
    render(conn, :index, products: products)
  end

  def show(conn, %{"id" => id}) do
    product = Products.get_product!(id)
    render(conn, :show, product: product)
  end
end

Handling Request Bodies: Create

When a client sends data to create a new resource (e.g., POST /products), that data is in the request body. Phoenix makes this data available in conn.body_params.

We typically pass this data to an Ecto Changeset for validation and then insert it into the database. If successful, we respond with the newly created resource; otherwise, we send an error.

Code: The `create` Action

Here's a simplified create action. Notice how we use conn.body_params and then render the result. (In a real app, create_product would involve Changesets and Ecto Repo calls).

Try to understand how the new product is rendered back to the client.

defmodule MyAppWeb.ProductController do
  use MyAppWeb, :controller
  alias MyApp.Products
  alias MyApp.Products.Product

  # ... other actions ...

  def create(conn, %{"product" => product_params}) do
    case Products.create_product(product_params) do
      {:ok, product} ->
        conn
        |> put_status(:created)
        |> render(:show, product: product)
      {:error, %Ecto.Changeset{} = changeset} ->
        conn
        |> put_status(:unprocessable_entity)
        |> render(MyAppWeb.ChangesetView, "error.json", changeset: changeset)
    end
  end

  # Dummy function for runnable code
  defp create_product(params) do
    # In a real app, this would save to DB with Ecto.Changeset
    # For demo, just return a dummy product
    product = %Product{id: 1, name: params["name"], price: params["price"], description: params["description"]}
    {:ok, product}
  end

  # For runnable context
  defmodule Product do
    defstruct [:id, :name, :price, :description]
  end
end

Handling Request Bodies: Update

The update action handles PUT or PATCH requests to modify an existing resource (e.g., PUT /products/:id). It's similar to create, but you first retrieve the existing resource.

The updated data is also found in conn.body_params. After validating and updating the resource, you typically respond with the updated resource or an error.

defmodule MyAppWeb.ProductController do
  use MyAppWeb, :controller
  alias MyApp.Products
  alias MyApp.Products.Product

  # ... other actions ...

  def update(conn, %{"id" => id, "product" => product_params}) do
    product = Products.get_product!(id)

    case Products.update_product(product, product_params) do
      {:ok, product} ->
        render(conn, :show, product: product)
      {:error, %Ecto.Changeset{} = changeset} ->
        conn
        |> put_status(:unprocessable_entity)
        |> render(MyAppWeb.ChangesetView, "error.json", changeset: changeset)
    end
  end

  # Dummy functions for runnable context
  defp get_product!(id), do: %Product{id: String.to_integer(id), name: "Old Name", price: "10.0", description: "Old Description"}
  defp update_product(product, params) do
    updated_product = %{product | name: Map.get(params, "name", product.name), price: Map.get(params, "price", product.price)}
    {:ok, updated_product}
  end

  defmodule Product do
    defstruct [:id, :name, :price, :description]
  end
end

What is Serialization?

Serialization is the process of converting Elixir data structures (like structs or maps) into a format that can be easily transmitted over a network or stored. For APIs, this usually means converting Elixir data into JSON (JavaScript Object Notation).

Why is it important? It allows different systems (your Elixir backend and a mobile app or web frontend) to understand and exchange data consistently.

Basic JSON Serialization with `render`

Phoenix uses views to handle serialization. When you call render(conn, :show, product: product) in a controller, Phoenix looks for a corresponding view module (e.g., ProductView) and a function (e.g., render("show.json", %{product: product})).

This function then defines how the Elixir product struct should be transformed into a JSON map.

defmodule MyAppWeb.ProductView do
  use MyAppWeb, :view

  def render("index.json", %{products: products}) do
    %{data: render_many(products, __MODULE__, :product)}
  end

  def render("show.json", %{product: product}) do
    %{data: render_one(product, __MODULE__, :product)}
  end

  def product(product) do
    %{id: product.id,
      name: product.name,
      description: product.description,
      price: product.price}
  end
end

Customizing JSON Output

The product/1 function within ProductView is where you define the exact structure of your JSON response. You can:

  • Select specific fields to include or exclude.
  • Rename fields for client-friendliness.
  • Nest related data (e.g., include a product's category).

This gives you fine-grained control over what data your API exposes and how it's structured.

Quick Check: Request Bodies

Consider a Phoenix API endpoint designed to create a new user. A client sends a POST request to /api/users with a JSON body:

{"user": {"name": "Alice", "email": "alice@example.com"}}

Which part of the conn struct holds the data {"name": "Alice", "email": "alice@example.com"}?

Recap: Endpoints & Serialization

Great job! You've learned how to build and understand Phoenix API endpoints:

  • API Endpoints: Specific URLs for resource actions.
  • Request Bodies: Data sent by clients (e.g., for POST/PUT) is in conn.body_params.
  • Serialization: Converting Elixir data to JSON for API responses, primarily handled by Phoenix views.
  • Customization: Views allow you to control the exact JSON structure.

These concepts are fundamental to building robust and client-friendly RESTful APIs with Phoenix!

الأسئلة الشائعة

هل درس «تطبيق نقاط نهاية API وتسلسل البيانات» مجاني؟

نعم — نص درس «تطبيق نقاط نهاية API وتسلسل البيانات» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Elixir & Phoenix: Scalable Backend Development، انتقل إلى CoddyKit PRO. تتضمن دورة Elixir & Phoenix: Scalable Backend Development 4 دروس في المجموع.

ماذا ستتعلم في «تطبيق نقاط نهاية API وتسلسل البيانات»؟

ابنوا نقاط نهاية API، وتعاملوا مع أجسام الطلبات والاستجابات، وقوموا بتسلسل البيانات بكفاءة لاستخدام العملاء. تتمرن على Elixir & Phoenix: Scalable Backend Development مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ Elixir & Phoenix: Scalable Backend Development؟

لا تُشترط خبرة سابقة. Elixir & Phoenix: Scalable Backend Development على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 2 من أصل 4.

كم من الوقت يستغرق درس «تطبيق نقاط نهاية API وتسلسل البيانات»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس Elixir & Phoenix: Scalable Backend Development هذا؟

نعم. كل درس في Elixir & Phoenix: Scalable Backend Development يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. مبادئ تصميم API وأفضل ممارساته
  2. تطبيق نقاط نهاية API وتسلسل البيانات
  3. استراتيجيات المصادقة والتفويض
  4. تقسيم الصفحات والتصفية وإصدار واجهات API
← العودة إلى Elixir & Phoenix: Scalable Backend Development