8. Reading Data (GET)
- Reading Data (GET)
About this chapter
Implement safe, efficient GET endpoints to retrieve data from your API using query parameters, route parameters, and proper HTTP status codes.
- Simple GET endpoints: Retrieving collections with pagination
- GET by ID: Route parameters and named routes
- HTTP status codes: 200 OK, 404 NotFound responses
- Query parameters: Filtering, sorting, and pagination options
- DTOs in responses: Shaping data for clients
- Error handling: Handling missing resources gracefully
Learning outcomes:
- Create paginated GET endpoints for collections
- Implement GET by ID with proper 404 handling
- Use route parameters and query parameters correctly
- Design DTOs for read operations
- Return appropriate HTTP status codes
- Apply AutoMapper for data transformation
8.1 Simple GET Endpoints
[HttpGet]
public async Task<ActionResult<PaginatedList<PlatformReadDto>>> GetPlatforms(
int pageIndex = 1,
int pageSize = 10)
{
var platforms = await _repository.GetPlatformsAsync(pageIndex, pageSize);
var platformDtos = _mapper.Map<PaginatedList<PlatformReadDto>>(platforms);
return Ok(platformDtos);
}
- Query Parameters: Passed in URL: /api/platforms?pageIndex=2&pageSize=20
- Default Values: Provide sensible defaults
- Return Type: ActionResult
for proper OpenAPI documentation
8.2 GET by ID with Route Parameters
[HttpGet("{id}", Name = "GetPlatformById")]
public async Task<ActionResult<PlatformReadDto>> GetPlatformById(int id)
{
var platform = await _repository.GetPlatformByIdAsync(id);
if (platform == null)
return NotFound(); // 404
var platformDto = _mapper.Map<PlatformReadDto>(platform);
return Ok(platformDto); // 200
}
- Route Parameter: {id} in route maps to int id parameter
- Naming Routes: Used for CreatedAtRoute() in POST
8.3 Returning 404 NotFound Appropriately
// ❌ Don't return null or throw exception
public async Task<PlatformReadDto> GetPlatform(int id)
{
return await _repository.GetPlatformByIdAsync(id); // Returns null?
}
// ✅ Return proper status code
public async Task<ActionResult<PlatformReadDto>> GetPlatform(int id)
{
var platform = await _repository.GetPlatformByIdAsync(id);
if (platform == null)
return NotFound(); // HTTP 404
return Ok(_mapper.Map<PlatformReadDto>(platform)); // HTTP 200
}
//✅ With custom message
if (platform == null)
return NotFound(new { message = $"Platform with ID {id} not found" });
8.4 NEW: ProducesResponseType Attributes
[HttpGet("{id}", Name = "GetPlatformById")]
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(PlatformReadDto))]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
public async Task<ActionResult<PlatformReadDto>> GetPlatformById(int id)
{
// Implementation...
}
- Benefits:
- Better Swagger documentation
- Client code generation accuracy
- Contract documentation
- Apply to ALL Endpoints: Documents possible responses