Let's say I want to implement a User API Controller. Client needs to get users by integer ID, so I create a method GET - /api/User/{id:int}
.
Then for some reason I want to implement getting a user by its name. The most obvious solution is to create GET - /api/User/{name:string}
but this method will be conflicting with the previous one. Naming a method /api/UserByName/{name:string}
breaks REST entity rules.
How can I deal with this problem without breaking REST rules?
Update: I just wrote the following code to create multiple routes:
[HttpGet]
public async Task<IActionResult> Get([FromQuery] int id)
{
return Ok();
}
[HttpGet]
public async Task<IActionResult> Get([FromQuery] string name)
{
return Ok();
}
This code cannot be translated by swagger and produces an error:
Swashbuckle.AspNetCore.SwaggerGen.SwaggerGeneratorException: Conflicting method/path combination "GET WeatherForecast" for actions - WebApiSkeleton.API.Contro llers.WeatherForecastController.Get (WebApiSkeleton.API),WebApiSkeleton.API.Controllers.WeatherForecastController.Get (WebApiSkeleton.API). Actions require a unique method/path combination for Swagger/OpenAPI 3.0. Use ConflictingActionsResolver as a workaround
Calling a method raises another exception:
Microsoft.AspNetCore.Routing.Matching.AmbiguousMatchException: The request matched multiple endpoints. Matches:
WebApiSkeleton.API.Controllers.WeatherForecastController.Get (WebApiSkeleton.API)
WebApiSkeleton.API.Controllers.WeatherForecastController.Get (WebApiSkeleton.API)
What I did mean by using [FromQuery] is this. It would required for you to have a class with id and name
public class UserFilter
{
public int? Id { get; set; }
public string Name { get; set; }
}
Then have the route like this
[HttpGet]
public async Task<IActionResult> Get([FromQuery] UserFilter filter)
{
if (filter.Id.HasValue)
{
// Search by id
}
else if (!string.IsNullOrWhiteSpace(filter.Name))
{
// Searh by name
}
return BadRequest();
}