×
Back to book

Custom API endpoint with C#Bot

In this article, we will create an extra endpoint to an existing entity while enforcing C# security and easily adding to the Swagger API docs.

C#Bot usually uses REST API architecture to add customized endpoints.

In this article, an extra custom REST API controller will be created in a new file (if it doesn't already exist), and place an endpoint in it that performs a specific action without circumvening the C#Bot's security requirements. It'll also incorparate the Swagger API docs to ensure documentation stays up-to-date as the API evolves. The creation of the endpoint will be based on the below user story.

User Story : As a Zoo Keeper I want to flag when a Tank enclosure is at capacity so that I can properly manage the locations of the animals.

To align with the given user story, the new custom endpoint is to only return enclosures with the enclosure type Tank where capacity is set to true.

You will be required to interact with the following files on the server-side:

File Name Relative Path Purpose
EnclosureManagementController.cs (Create it if you haven't) serverside/src/controllers/EnclosureManagementController.cs Controller used to handle all customized REST operations. It contains the URL endpoints and the Swagger Docs

EnclosureManagementsController.cs

Create the above .cs file and give it an EnclosureManagementsController class that inherits from the entity framework's Controller class. The ASP.NET core framework allows RESTful endpoints to be created inside the controllers via normal methods.

What is special about these methods is that they contain C# annotation to register themselves as endpoints.

Add the following code inside the new controller file:

using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Zoo.Models;
using Zoo.Services;

namespace Zoo.Controllers
{
    [Route("/api/enclosure-management")]
    [Authorize]
    [ApiController]
    public class EnclosureManagementController : Controller
    {
        private readonly EnclosureManagementService _managementService;

        public EnclosureManagementController(EnclosureManagementService managementService)
        {
            _managementService = managementService;
        }

        [HttpGet]
        [Route("get-enclosures-at-capacity")]
        public async Task<IEnumerable<EnclosureDto>> GetFullTankEnclosuresAtCapacity()
        {
            var enclosures = await _managementService
                .GetFullTankEnclosuresAtCapacity()
                .ToListAsync();
            return enclosures.Select(e => new EnclosureDto(e));
        }
    }
}

Annotations - Class

  • [Route("/api/enclosure-management")] specifies the root URL of the endpoint.
  • [Authorize] means this controller can only be accessed if the user is logged in. We could use the [AllowAnonymous] annotation on specific endpoint functions to override the class annotation.
  • [ApiController] is to register this class as API controller.

Annotations - Method

  • [HttpGet] routes the Http get request to GetFullTankEnclosuresAtCapacity endpoint
  • [Route("get-fulltank-enclosures-at-capacity")] specifies the URL slug of this endpoint which will be concatenated with root URL to form the whole relative URL /api/enclosure-management/get-enclosures-at-capacity which the front-end request should use to call this endpoint.

Calling Service

GetEnclosuresAtCapacity calls EnclosureManagementService.GetFullTankEnclosures function to query the database with the specific logic of this example needs.

The following code is the implementation of the GetFullTankEnclosures action to get all the enclosures with the enclosure type Tank where capacity is set to true.

public IQueryable<Enclosure> GetFullTankEnclosures()
{
    return _crudService.Get<Enclosure>()
        .Where(e => e.Capacity == true)
        .Where(e => e.EnclosureType == AnimalEnclosureType.TANK);
}

Security

Calling _crudService.Get<Enclosure> to get the entities data will enforce the C# security configurations. However, calling the ZooDBContext directly to get data is not recommended as this bypasses the security configurations.

Conclusion

This tutorial has demonstrated how to create and secure a new Restful API endpoint. The new endpoint can now be tested by starting the backend server, and then navigating to Swagger.

Related Articles