Begin with a small, real integration surface
Warehouse REST API design is easiest to inspect through a complete feature. The Warehouse feature in Blazor WMS Source Code exposes list, detail, create, update, and delete operations. This guide documents that source contract and separates it from potential API improvements. It does not assume routes based only on conventional REST naming.
Resolve the full route from the application root
Program.cs creates an /api group and maps feature endpoints onto it. WarehouseEndpoint then creates a /warehouse subgroup. Together they form the following routes; the service calls use the same prefix.
| Method | Route | Action |
|---|---|---|
| GET | /api/warehouse | List warehouses. |
| GET | /api/warehouse/{id} | Read one warehouse. |
| POST | /api/warehouse | Create a warehouse. |
| POST | /api/warehouse/update | Update using the request DTO. |
| POST | /api/warehouse/delete/{id} | Delete an eligible warehouse through its handler. |
An integration should not substitute PUT or DELETE without changing the server contract. Those verbs could be part of a future API redesign, but they are not the methods mapped by the inspected warehouse endpoint. The list query orders by Name and returns a list; it is not a demonstrated paginated warehouse-list API.
Send the create payload with bearer authentication
The warehouse route group explicitly selects the JWT bearer authentication scheme and requires an authenticated user. A caller needs an accepted bearer token. The inspected group does not itself specify an administrator role requirement, so role-specific restrictions should not be claimed from this declaration alone.
POST /api/warehouse
Authorization: Bearer <access-token>
Content-Type: application/json
{
"name": "Main Warehouse",
"description": "Primary storage location",
"systemWarehouse": false
}
This is an illustrative HTTP request, not a credential-bearing command to run against the demo. The request DTO contains nullable Name and Description strings and a nullable SystemWarehouse flag initialized to false. The create handler maps these fields into Warehouse, checks whether the name exists, and returns an Id and Name response payload.
Read the envelope and transport status separately
ApiResponse<T> contains IsSuccess, StatusCode, Message, Value, Pagination, Errors, and ServerTime. Value is the typed operation result. ServerTime changes per response. The exact serialized field naming follows the application’s JSON configuration; integrations should verify a response from their own running instance.
The create endpoint passes 201 into ToApiResponse, but the inspected helper returns Results.Ok for a non-null result. The HTTP response is therefore 200 while the envelope’s StatusCode is 201. Null results use Results.NotFound and a 404 envelope. Do not describe this endpoint as returning HTTP 201 Created solely because its method call contains Status201Created.
// Relevant behavior from GenericExtensions.ToApiResponse
return Results.Ok(new ApiResponse<T>
{
IsSuccess = true,
StatusCode = statusCode,
Message = message,
Value = result,
Pagination = null,
ServerTime = DateTime.UtcNow
});
Trace validation instead of assuming it is automatic
CreateWarehouseValidator targets CreateWarehouseRequest. Its rules require Name and limit Name to 500 characters and Description to 1000. The Blazor form explicitly uses that validator. The endpoint, however, sends CreateWarehouseCommand to MediatR. The shared validation behavior resolves validators for the dispatched request type, which is the command wrapper.
Consequently, this DTO validator alone is not evidence of server enforcement for direct create requests. To extend the API with guaranteed payload validation, explicitly invoke the DTO validator or add a command validator that validates Data, then test it through HTTP. That is a proposed improvement, not a claim that this article has changed the application.
Handle business failures and retries deliberately
CreateWarehouseHandler performs an AnyAsync name-existence check and throws AlreadyExistsException when it finds a match. DeleteWarehouseByIdHandler returns false for a missing warehouse or one marked SystemWarehouse. Its endpoint converts that failure into a null-result response. A successful deletion goes through AppDbContext’s soft-delete behavior.
The name lookup is an application check; it does not alone establish race-free uniqueness or idempotent creation. Before adding automatic retries for an integration, define how a timed-out request is reconciled and whether repeating it can create another operation. For inventory writes, review the relevant document handler instead of guessing that a warehouse-maintenance route also accepts stock movements.
Use focused contract checks
- Call list and detail with a valid token; inspect both HTTP status and the response body.
- Check a missing identifier, an unauthenticated call, a duplicate name, and a system-warehouse delete.
- Send invalid data directly to the API to verify actual server-side validation.
- Test the implemented update and delete methods rather than inferred REST verbs.
The vertical slice guide follows the handler and UI path behind these endpoints. For the full set of source files and business features, continue to Blazor WMS Source Code.