Skip to content

Commit 416a004

Browse files
nanotaboadaclaude
andcommitted
refactor(api)!: add /squadNumber/ path segment to routes (#418)
BREAKING CHANGE: old /players/{int} routes return 404; use /players/squadNumber/{int} instead. Co-authored-by: Claude <noreply@anthropic.com>
1 parent 7492483 commit 416a004

2 files changed

Lines changed: 17 additions & 13 deletions

File tree

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -218,10 +218,10 @@ Interactive API documentation is available via Swagger UI at `https://localhost:
218218

219219
- `GET /players` - List all players
220220
- `GET /players/{id:Guid}` - Get player by ID (requires authentication)
221-
- `GET /players/{squadNumber:int}` - Get player by squad number
221+
- `GET /players/squadNumber/{squadNumber:int}` - Get player by squad number
222222
- `POST /players` - Create new player
223-
- `PUT /players/{squadNumber}` - Update player
224-
- `DELETE /players/{squadNumber}` - Remove player
223+
- `PUT /players/squadNumber/{squadNumber}` - Update player
224+
- `DELETE /players/squadNumber/{squadNumber}` - Remove player
225225
- `GET /health` - Health check
226226

227227
For complete endpoint documentation with request/response schemas, explore the [interactive Swagger UI](https://localhost:9000/swagger/index.html).

src/Dotnet.Samples.AspNetCore.WebApi/Controllers/PlayerController.cs

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ public async Task<IResult> GetByIdAsync([FromRoute] Guid id)
124124
/// <param name="squadNumber">The Squad Number of the Player</param>
125125
/// <response code="200">OK</response>
126126
/// <response code="404">Not Found</response>
127-
[HttpGet("{squadNumber:int}", Name = "RetrieveBySquadNumber")]
127+
[HttpGet("squadNumber/{squadNumber:int}", Name = "RetrieveBySquadNumber")]
128128
[ProducesResponseType<PlayerResponseModel>(StatusCodes.Status200OK)]
129129
[ProducesResponseType(StatusCodes.Status404NotFound)]
130130
public async Task<IResult> GetBySquadNumberAsync([FromRoute] int squadNumber)
@@ -133,15 +133,15 @@ public async Task<IResult> GetBySquadNumberAsync([FromRoute] int squadNumber)
133133
if (player != null)
134134
{
135135
logger.LogInformation(
136-
"GET /players/{SquadNumber} retrieved: {@Player}",
136+
"GET /players/squadNumber/{SquadNumber} retrieved: {@Player}",
137137
squadNumber,
138138
player
139139
);
140140
return TypedResults.Ok(player);
141141
}
142142
else
143143
{
144-
logger.LogWarning("GET /players/{SquadNumber} not found", squadNumber);
144+
logger.LogWarning("GET /players/squadNumber/{SquadNumber} not found", squadNumber);
145145
return TypedResults.NotFound();
146146
}
147147
}
@@ -159,7 +159,7 @@ public async Task<IResult> GetBySquadNumberAsync([FromRoute] int squadNumber)
159159
/// <response code="204">No Content</response>
160160
/// <response code="400">Bad Request</response>
161161
/// <response code="404">Not Found</response>
162-
[HttpPut("{squadNumber:int}", Name = "Update")]
162+
[HttpPut("squadNumber/{squadNumber:int}", Name = "Update")]
163163
[Consumes(MediaTypeNames.Application.Json)]
164164
[ProducesResponseType(StatusCodes.Status204NoContent)]
165165
[ProducesResponseType(StatusCodes.Status400BadRequest)]
@@ -177,20 +177,24 @@ [FromBody] PlayerRequestModel player
177177
.ToArray();
178178

179179
logger.LogWarning(
180-
"PUT /players/{SquadNumber} validation failed: {@Errors}",
180+
"PUT /players/squadNumber/{SquadNumber} validation failed: {@Errors}",
181181
squadNumber,
182182
errors
183183
);
184184
return TypedResults.BadRequest(errors);
185185
}
186186
if (await playerService.RetrieveBySquadNumberAsync(squadNumber) == null)
187187
{
188-
logger.LogWarning("PUT /players/{SquadNumber} not found", squadNumber);
188+
logger.LogWarning("PUT /players/squadNumber/{SquadNumber} not found", squadNumber);
189189
return TypedResults.NotFound();
190190
}
191191
await playerService.UpdateAsync(player);
192192
// codeql[cs/log-forging] Serilog structured logging with @ destructuring automatically escapes control characters
193-
logger.LogInformation("PUT /players/{SquadNumber} updated: {@Player}", squadNumber, player);
193+
logger.LogInformation(
194+
"PUT /players/squadNumber/{SquadNumber} updated: {@Player}",
195+
squadNumber,
196+
player
197+
);
194198
return TypedResults.NoContent();
195199
}
196200

@@ -204,20 +208,20 @@ [FromBody] PlayerRequestModel player
204208
/// <param name="squadNumber">The Squad Number of the Player</param>
205209
/// <response code="204">No Content</response>
206210
/// <response code="404">Not Found</response>
207-
[HttpDelete("{squadNumber:int}", Name = "Delete")]
211+
[HttpDelete("squadNumber/{squadNumber:int}", Name = "Delete")]
208212
[ProducesResponseType(StatusCodes.Status204NoContent)]
209213
[ProducesResponseType(StatusCodes.Status404NotFound)]
210214
public async Task<IResult> DeleteAsync([FromRoute] int squadNumber)
211215
{
212216
if (await playerService.RetrieveBySquadNumberAsync(squadNumber) == null)
213217
{
214-
logger.LogWarning("DELETE /players/{SquadNumber} not found", squadNumber);
218+
logger.LogWarning("DELETE /players/squadNumber/{SquadNumber} not found", squadNumber);
215219
return TypedResults.NotFound();
216220
}
217221
else
218222
{
219223
await playerService.DeleteAsync(squadNumber);
220-
logger.LogInformation("DELETE /players/{SquadNumber} deleted", squadNumber);
224+
logger.LogInformation("DELETE /players/squadNumber/{SquadNumber} deleted", squadNumber);
221225
return TypedResults.NoContent();
222226
}
223227
}

0 commit comments

Comments
 (0)