Tuesday, 9 September 2014

Implementing API in ASP.NET MVC application

Full project can be downloaded here.

We are going to create simple API that will return either collection of movies or single movie in Json format by default, however depends on browser results might be displayed in XML format.
I focused only on GET method in this tutorial.
 
1. Create new MVC application in Visual Studio.
2. In models create interface IMoviesRepository, class Movie and MoviesRepository

public interface IMoviesRepository
    {
        IQueryable<Movie> GetAll();
        Movie GetById(int id);
        Movie Add(Movie movie);
        bool Edit(Movie movie);
        bool Remove(Guid? id);
    }

public class Movie
    {
        public int movieId { get; set; }
        public string name { get; set; }
        public string releaseYear { get; set; }
    }

public class MovieRepository : IMoviesRepository
    {
        private List<Movie> _listOfMovies = new List<Movie>();

        public MovieRepository()
        {
            _listOfMovies.Add(new Movie { 
                movieId = 1,
                name = "Keyboard massacre", 
                releaseYear = "1999" });

            _listOfMovies.Add(new Movie { 
                movieId = 2, 
                name = "Keyboard massacre 2",
                releaseYear = "2000" });

            _listOfMovies.Add(new Movie { 
                movieId = 3,
                name = "Keyboard massacre 3 ",
                releaseYear = "2001" });
        }

        public IQueryable<Movie> GetAll()
        {
            return _listOfMovies.AsQueryable();
        }

        public Movie GetById(int id)
        {
            return _listOfMovies.Find(m => m.movieId == id);
        }

        public Movie Add(Movie movie)
        {
            throw new NotImplementedException();
        }

        public bool Edit(Movie movie)
        {
            throw new NotImplementedException();
        }

        public bool Remove(Guid? id)
        {
            throw new NotImplementedException();
        }
    }
Create interface first and then MovieRepository that will inherit IMoviesRepository and simply right click on class name and apply Implement Interface.



3. Add new folder to your main project WebApiControllers and add Api Controller. Call itMoviesController.cs.



Add this to your main controller class.


MovieRepository movieRepository;

        public MoviesController()
        {
            this.movieRepository = new MovieRepository();
        } 


Calling default constructor will make sure that all repositories are in place. It is good practice to call all services that will be required for controller - we are making sure that our application is loose coupled. If you are familiar with dependency injection this is quite common concept.

As I mentioned I will focus only on GET method, so replace both GET methods with custom code.

You controller should like this :


public class MoviesController : ApiController
    {
        MovieRepository movieRepository;

        public MoviesController()
        {
            this.movieRepository = new MovieRepository();
        }

        // GET api/movies
        public IQueryable<Movie> Get()
        {
            return movieRepository.GetAll();
        }

        // GET api/movies/5
        public Movie Get(int id)
        {
            return movieRepository.GetById(id);
        }

        // POST api/movies
        public void Post([FromBody]string value)
        {
        }

        // PUT api/movies/5
        public void Put(int id, [FromBody]string value)
        {
        }

        // DELETE api/movies/5
        public void Delete(int id)
        {
        }
    }

4. Run your application now and call localhost:YourPortNumber/api/movies

In my case: http://localhost:53909/api/movies

You should get this results in Chrome:


If you run it in IE you will be asked to save file. By opening it in notepad you get JSON results

[{"movieId":1,"name":"Keyboard massacre","releaseYear":"1999"},{"movieId":2,"name":"Keyboard massacre 2","releaseYear":"2000"},{"movieId":3,"name":"Keyboard massacre 3 ","releaseYear":"2001"}]

5. We could improve GetById method. If movie can not be found we want to return HttpResponseException.

// GET api/movies/5
        public Movie Get(int id)
        {
            var movie = movieRepository.GetById(id);
            if (movie == null)
            {
                throw new HttpResponseException(HttpStatusCode.NotFound);
            }
            return movie;
        }

6. There are few rules that you have to be aware. You have to name your GET method starting with Get. So For instance GetCollectionOfMovies. By calling http://localhost:53909/api/movies you get the same results as if your method would call just Get. There is a way to force user to type full name of your method http://localhost:53909/api/GetCollectionOfMovies and this will require changing routing in Global.asax file. I will mention that in one of next tutorials.