How to Customize Endpoint Names in FastCRUD's crud_router: A Complete Guide

You can customize endpoint names in crud_router by passing an endpoint_names dictionary that maps operation keys like "create", "read", and "delete" to your desired URL path segments, allowing you to override the default REST conventions used by the benavlabs/fastcrud library.

The crud_router function in FastCRUD automatically generates FastAPI routes for your SQLAlchemy models. By default, it creates standard REST endpoints, but you can fully customize the URL structure using the endpoint_names parameter to match your API's naming conventions or legacy requirements.

Understanding the endpoint_names Parameter

The endpoint_names parameter accepts a dictionary where keys represent CRUD operations and values define the URL path segment for that operation. The supported keys are:

  • "create" – POST endpoint for creating records
  • "read" – GET endpoint for retrieving a single record
  • "update" – PATCH/PUT endpoint for modifying records
  • "delete" – DELETE endpoint for soft deletes
  • "db_delete" – DELETE endpoint for hard/permanent deletes
  • "read_multi" – GET endpoint for listing multiple records

Default Endpoint Name Behavior

According to the source code in fastcrud/endpoint/endpoint_creator.py (lines 28-36), the EndpointCreator class defines the following default mapping:

self.default_endpoint_names = {
    "create": "",
    "read": "",
    "update": "",
    "delete": "",
    "db_delete": "db_delete",
    "read_multi": "",
}

Most operations default to an empty string, meaning they use the base path directly (e.g., /tasks). Only db_delete has a non-empty default of "db_delete" (resulting in /tasks/db_delete/{id}).

How Endpoint Names Are Resolved in the Source Code

The actual path resolution occurs in the _get_endpoint_path method within fastcrud/endpoint/endpoint_creator.py (lines 52-57). This method merges your custom endpoint_names with the defaults and constructs the final URL:

endpoint_name = self.endpoint_names.get(
    operation, self.default_endpoint_names.get(operation, operation)
)
path = f"{self.path}/{endpoint_name}" if endpoint_name else self.path

For operations that involve primary keys (read, update, delete, and db_delete), the router automatically appends the primary key parameters after the operation segment (lines 58-63). This results in paths like /tasks/custom_name/{id}.

Practical Examples for Customizing Endpoint Names

Basic Usage with Custom Names

To completely rename all endpoints for a task management API, pass a comprehensive endpoint_names dictionary to crud_router:

from fastapi import FastAPI
from fastcrud import crud_router
from .database import async_session
from .models import Task
from .schemas import CreateTaskSchema, UpdateTaskSchema

app = FastAPI()

task_router = crud_router(
    session=async_session,
    model=Task,
    create_schema=CreateTaskSchema,
    update_schema=UpdateTaskSchema,
    path="/tasks",
    tags=["Task Management"],
    endpoint_names={
        "create": "add_task",
        "read": "get_task",
        "update": "modify_task",
        "delete": "remove_task",
        "db_delete": "permanently_remove_task",
        "read_multi": "list_tasks",
    },
)

app.include_router(task_router)

This configuration generates the following routes:

  • POST /tasks/add_task – Create a task
  • GET /tasks/get_task/{id} – Retrieve a single task
  • PATCH /tasks/modify_task/{id} – Update a task
  • DELETE /tasks/remove_task/{id} – Soft delete a task
  • DELETE /tasks/permanently_remove_task/{id} – Hard delete a task
  • GET /tasks/list_tasks – List all tasks

Customizing Only Specific Operations

You can override only the operations you care about while keeping the defaults for others. This example customizes only the creation and listing endpoints:

user_router = crud_router(
    session=async_session,
    model=User,
    create_schema=CreateUserSchema,
    update_schema=UpdateUserSchema,
    path="/users",
    tags=["Users"],
    endpoint_names={
        "create": "register",
        "read_multi": "search",
    },
)

This generates:

  • POST /users/register – Create user (custom)
  • GET /users/{id} – Read user (default)
  • PATCH /users/{id} – Update user (default)
  • GET /users/search – List users (custom)

Mixing Custom and Default Names

When you want most endpoints to use the base path but need specific exceptions, provide an empty string for defaults and custom strings for exceptions:

order_router = crud_router(
    session=async_session,
    model=Order,
    create_schema=CreateOrderSchema,
    update_schema=UpdateOrderSchema,
    path="/orders",
    tags=["Orders"],
    endpoint_names={
        "read_multi": "list",   # Custom: /orders/list

        # All others default to empty string → /orders

    },
)

This configuration results in:

  • POST /orders – Create
  • GET /orders/{id} – Read
  • PATCH /orders/{id} – Update
  • GET /orders/list – List all
  • DELETE /orders/{id} – Soft delete
  • DELETE /orders/db_delete/{id} – Hard delete (uses default db_delete suffix)

Summary

  • Use the endpoint_names parameter in crud_router to customize URL paths for CRUD operations.
  • Valid keys include "create", "read", "update", "delete", "db_delete", and "read_multi".
  • Default behavior uses empty strings for most operations (base path only) except "db_delete" which defaults to "db_delete".
  • Path resolution occurs in fastcrud/endpoint/endpoint_creator.py via the _get_endpoint_path method, which merges custom names with defaults.
  • Primary key routes automatically append /{pk} after the custom endpoint name segment.

Frequently Asked Questions

What are the valid keys for the endpoint_names dictionary?

The endpoint_names dictionary accepts six string keys that correspond to the CRUD operations generated by FastCRUD: "create" (POST), "read" (GET single), "update" (PATCH/PUT), "delete" (soft DELETE), "db_delete" (hard DELETE), and "read_multi" (GET list). Each key maps to a string value that becomes the URL path segment for that operation.

Can I use empty strings in endpoint_names?

Yes, empty strings are valid values and represent the default behavior where the operation uses the base path directly without any additional suffix. For example, setting "create": "" results in the endpoint POST /tasks (assuming your base path is /tasks). This is how FastCRUD handles most operations by default, except for db_delete which uses "db_delete" as its default suffix.

How do primary key parameters affect custom endpoint paths?

For operations that target specific records (read, update, delete, and db_delete), FastCRUD automatically appends the primary key parameters to the end of the custom path segment. For example, if you set "read": "fetch_item", the resulting route becomes GET /tasks/fetch_item/{id} rather than just GET /tasks/fetch_item. This behavior is hardcoded in the _get_endpoint_path method within fastcrud/endpoint/endpoint_creator.py.

Where is the endpoint name logic implemented in FastCRUD?

The core logic for resolving endpoint names resides in the EndpointCreator class located at fastcrud/endpoint/endpoint_creator.py. Specifically, the __init__ method (lines 28-36) handles the merging of user-provided endpoint_names with default values, while the _get_endpoint_path method (lines 52-63) constructs the final URL paths by looking up operation names in the merged dictionary and appending primary key segments where appropriate.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →