Build By Example
Here is a simple Web API of a Todo App using Quickie for Minimal API project.
Step 1: Create a new Web API Project
dotnet new webapi -n todo.apis
Step 2: Install Quickie
Install Quickie from NuGet:
dotnet add package Quickie
Step 3: Configure Quickie in Program.cs
In your Program.cs
, configure Quickie as follows:
builder.Services.QuickieConfig();
app.AddQuickie();
Explanation:
- For this project, default configuration will be used as shown above.
More on configuration here
Step 4: Create a Dto and Entity
public record TodoCrudableDto(int Id, string Title, string Description) : CrudDto;
public class TodoCrudableEntity : CrudEntity
{
[Key]
public int Id { get; set; }
public required string Title { get; set; }
public required string Description { get; set; }
public required DateTime CreatedDate { get; set; }
}
Step 5: Create your apis
For our Todo app, we need CRUD operations:
- C -> Create Todo
- R -> Read Todo
- U -> Update Todo
- D -> Delete Todo
app.AddCrudEndpoints<TodoCrudableDto, ITodoService, int>("/api/todos");
Step 6: Request handler (Service layer) Setup
Todo Service
public interface ITodoService : ICrudRequestHandler<TodoCrudableDto, int>;
public class TodoService(ITodoRepo dataHandler) : CrudRequestHandler<TodoCrudableDto, TodoCrudableEntity, ITodoRepo, int>(dataHandler), ITodoService
{
protected override TodoCrudableEntity MapToEntity(TodoCrudableDto request)
{
var d = new TodoCrudableEntity()
{ Id = request.Id, Title = request?.Title, Description = request?.Description, CreatedDate = DateTime.Now };
return d;
}
protected override TodoCrudableDto MapToDto(TodoCrudableEntity request)
{
var d = request is not null ? new TodoCrudableDto(request.Id, request?.Title + " id:" + request?.Id, request?.Description) : default;
return d;
}
}
Note: Mapping must be done manually. You can use any mapping library or write your own logic.
Todo Repository (Data handler)
public interface ITodoRepo : ICrudDataHandler<TodoCrudableEntity, int>;
public class TodoRepo(ApplicationDbContext dbContext) : CrudDataHandler<TodoCrudableEntity, ApplicationDbContext, int>(dbContext), ITodoRepo;
Step 7: Configure Database Context
public class ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : DbContext(options)
{
public DbSet<TodoCrudableEntity> TodoCrudableEntity { get; set; }
}
Step 8: Register Services in DI
DI registration:
builder.Services.AddScoped<ITodoService, TodoService>();
builder.Services.AddScoped<ITodoRepo, TodoRepo>();
builder.Services.AddScoped<ICrudDataHandler<TodoEntity, int>, TodoRepo>();
Step 9: Making Request
Since Idempotency is disabled, X-Idempotency-Key
header is not required.
Example Request:
### Create Todo
POST http://localhost:5220/api/todos
Content-Type: application/json
{
"title": "Test Todo yayay",
"description": "Testing CRUD operations"
}
### Get Todo by ID
GET http://localhost:5220/api/todos/3
### Update Todo
PUT http://localhost:5220/api/todos/1
Content-Type: application/json
{
"title": "Updated Todo",
"description": "Updated description"
}
### Delete Todo
DELETE http://localhost:5220/api/todos/1
Your Minimal API is now ready with:
- CRUD functionality
- Built-in Idempotency (to prevent duplicate requests which is disabled for default configuration)
- Built-in Rate Limiting (enabled by default)
Not Just CRUD
Quickie is versatile and supports scenarios beyond CRUD operations:
- CRUD for Collection: Bulk create, read, update, and delete operations are supported, making it easy to handle multiple entities in a single request.
- Readonly: For entities where only read operations are required.
// Get only (Single Entity)
app.AddReadOnlyEndpoints<TodoDto, ISingleTodoReqHandler, string>("/api/get/todos");
// Get only (Collection)
app.AddReadOnlyCollectionEndpoints<TodoDto, IReadTodoReqHandler, DataFilterRequest, string>("/api/getcollection/todos");
- Write-only: For scenarios where entities can only be written to, but not read.
// Write-only API
app.AddWriteOnlyEndpoints<WriteOnlyTodoDto, IWriteOnlyTodoReqHandler>("/api/create/todos");
- Edit-only: For entities that support updates but not creation or deletion.
// Edit-only API
app.AddEditOnlyEndpoints<PastTodo_EditOnlyDto, IEditOnlyTodoReqHandler, string>("/api/editonly/todos");
- Readonly Collections: You can define collections where only bulk read operations are required, and no modifications are allowed.
You can choose the appropriate functionality based on your application's needs.
That's it! Your fully functional Web API with:
- CRUD functionality
- Built-in Idempotency (to prevent duplicate requests)
- Built-in Rate Limiting (enabled by default)
Things to Consider
- DTOs should be record types.
- Entities are class (reference types).