Search code examples
.netasp.net-mvcentity-frameworkasp.net-mvc-routing

.NET Core 2 API attribute routing configuration


Suppose I have the following classes that are used to store data in a database using EF code first approach and that need to be consumed via a web REST API (.NET core 2.0 restful API)

public class Artist
{
    public long ArtistId  { get; set; }
    public string Name { get; set; }
    public ICollection<Song> Songs { get; set; }
}
public class Song
{
    public long SongId { get; set; }
    public long ArtistId { get; set; }
    public string Name { get; set; }
    public Artist Artist { get; set; }
}

Also, suppose that I have the following RESTFUL API controller

[Produces("application/json")]
[Route("api/Artists")]
public class ArtistsController : Controller
{
    private readonly ApiRepository repository;
    // GET: api/Artists/1
    [HttpGet("{id}")]
    public object GetArtist([FromRoute] long id)
    {
        return repository.GetArtist(id) ?? NotFound();
    }
    // GET: api/Artists/1/Song/4
    [HttpGet("How do I make this configuration?")]
    public object GetSong([FromRoute] long artistId, long songId)
    {
       // Get the artist from the artistId
       // Return the song corresponding to that artist
    }
}

At this point, I can access all artistis via https://www.myserver/api/Artists/1. However, I would like to be able to receive a song from an artist Id. Thus, my questions are as follow:

  1. How can I use attribute routing configuration on the method GetSong([FromRoute] long ArtistId, long songId) in order to have a route similar to https://www.myserver/api/Artists/1/Songs/1
  2. I feel like, if I use the approach described above, I will be forced to cram all the API methods into one controller. This will likely lead to a big controller class. Should I put the song related calls in a SongsController? And how would I configure this controller to stick to the routing described above?
  3. Is there any other recommended approach (pattern) for solving this problem?

Solution

  • To make the the Route as GET: api/Artists/1/Song/4

    // GET: api/Artists/1/Song/4
    [HttpGet("{artistId}/Song/{songId}")]
    public object GetSong([FromRoute] long artistId, long songId)
    {
       // Get the artist from the artistId
       // Return the song corresponding to that artist
    }