Lesson Tuesday

Over the weekend, you learned how to create an API and how to make a simple API call from a front-end client. Over the next several lessons, we're going to put these concepts together and build an MVC client with full CRUD functionality that will interact with our API.

First, let's discuss the structure of this project. We could put the API and the client (the application making the API calls) in the same repository. However, the point of our APIs is that they are modular and adaptable and can be accessed from any project. With that in mind, it makes more sense to keep our API and MVC projects in separate repositories, running on different ports.

Let's start building an MVC project that will call our API and display the results of our calls. The process of building out our client will be very similar to previous lessons where we learned how to use RestSharp, so these steps will not be laid out in as much detail as the initial lessons where we built an MVC application that made calls to the New York Times API. Also, these lessons will focus on communicating with an API, not on creating views, which you can do on your own.

Just like our MvcApiCall project, we'll create a new directory for our site. Outside of CretaceousPark.Solution, create a new directory called CretaceousClient.Solution, containing a .gitignore file and a CretaceousClient project folder. Inside the project folder, use the dotnet new mvc --framework net5.0 command to create the application. Then add the RestSharp and NewtonSoft.Json packages as shown in this lesson.

Next, we'll create an Animal class in the Models folder, utilizing the properties we defined in CretaceousPark along with a GetAnimals() method This requires very little new code and is very similar to code we built in the weekend lessons.

Models/Animal.cs
using System.Collections.Generic;
using System;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace CretaceousClient.Models
{
  public class Animal
  {
    public int AnimalId { get; set; }
    public string Name { get; set; }
    public string Species { get; set; }
    public int Age { get; set; }
    public string Gender { get; set; }

    public static List<Animal> GetAnimals()
    {
      var apiCallTask = ApiHelper.GetAll();
      var result = apiCallTask.Result;

      JArray jsonResponse = JsonConvert.DeserializeObject<JArray>(result);
      List<Animal> animalList = JsonConvert.DeserializeObject<List<Animal>>(jsonResponse.ToString());

      return animalList;
    }
  }
}

If we take a closer look at the ApiHelper class, we'll see that our method is called GetAll(). We'll need to provide routes for full CRUD functionality. Because an Index route will return a different data type than a Details route, we need a different method for each call. Also, notice that we don't pass an API key as an argument. Your personal API will not require a key unless you add Token-Based Authentication on your own.

Also, note that the jsonResponse object is of the type JArray as opposed to JObject. Since we're getting a collection of results, we need to expect an array of objects.

Next, let's actually create the ApiHelper class, which will contain the definition for our GetAll() method. Your API call should include the port that CretaceousPark is set to listen to. For the purposes of this project, we assume it listens on 5000 as it does in the example repo. If you choose to deploy an API at some point, you'll need to update the URL to include the domain of the deployed site instead of localhost. The endpoint itself for this particular call will be animals.

Models/ApiHelper.cs
using System.Threading.Tasks;
using RestSharp;

namespace CretaceousClient.Models
{
  class ApiHelper
  {
    public static async Task<string> GetAll()
    {
      RestClient client = new RestClient("http://localhost:5000/api");
      RestRequest request = new RestRequest($"animals", Method.GET);
      var response = await client.ExecuteTaskAsync(request);
      return response.Content;
    }
  }
}

In order to view our list of animals at localhost:5004/Animals, we still need to do the following:

  • Create a controller route
  • Create the corresponding views

We'll create an AnimalsController to handle these actions for us as well as Views/Animals/Index.cshtml. The code for these may vary, depending on the framework you use in your project. This project concerns basic Asp.NET Core Razor MVC structure without EF Core's simplifying functionality.

Controllers/AnimalsController.cs
...
public IActionResult Index()
{
  var allAnimals = Animal.GetAnimals();
  return View(allAnimals);
}
...
Views/Animals/Index.cshtml
<h1>All Animals:</h1>

<ol>
@foreach (Animal animal in Model)
{
    <ul>
        <li>ID: @animal.AnimalId</li>
        <li>Name: @animal.Name</li>
        <li>Species: @animal.Species</li>
        <li>Age: @animal.Age</li>
        <li>Gender: @animal.Gender</li>
    </ul>
    <a href="/Animals/Details/@(animal.AnimalId)"><p>View Details</p></a>
    <br>
}
</ol>

And that's it!

In the next lesson, we'll discuss making an API call for a single animal's details.

Lesson 18 of 22
Last updated April 6, 2022