.NET APIs Part 5 – All the CRUD APIs

In the previous posting we saw how to create an API to get all the cars in our database. In this posting we’ll look at the remaining CRUD (Create Review Update Delete) operations.

As you may remember, we created a controller named CarController. ASP.NET will strip off the word Controller, leaving us with Car, which we will use to access the endpoints of our API.

An endpoint is just a URL that takes us to the operation we want.

We looked at GetAll, let’s take a look at Get. In this case, we have an id for the car we want, but we want all the details of that car. Simple!

First we need a method in our controller:

[HttpGet("{id}")]
public async Task<ActionResult<Car>> Get(int id)
{
   var car = await _carRepository.Get(id);
   if (car == null)
   {
      return NotFound();
   }
   return car;
}


Notice that next to the HttpGet attribute we indicate that the endpoint will take the id of the car we want

[HttpGet("{id}")]

This means we need to modify the URL to access the endpoint by adding the actual id of the desired record.

The first thing we do is call the repository, passing in the id.

public async Task<Car?> Get(int id)
{
   var query = "select * from car where id=@id";
   using var db = databaseConnectionFactory.GetConnection();
   return await db.QuerySingleOrDefaultAsync<Car>(query, new {id});
}

In the Get method of the repo we create our query, get our connection and execute the query returning the value we retrieved (if any). This is very close to what we did previously.

Back in the controller, we check to ensure that we received a Car. If not, we return NotFound which is a shorthand way of returning a 404 message. Otherwise we return the Car as a Json object. You can see this in Postman:

We’ll issue a Get command passing in the URL, ending with the id of the car we want (in this case 4)

 

 

 

Notice that we get back a 200, indicating success. In the body of the returned Json we get back all the details of the Car. (If you decide to use DTOs you can get whatever subset of the information makes sense):

{
    “id”: 4,
    “name”: “subaru impreza”,
    “mpg”: “16”,
    “cylinders”: “8”,
    “displacement”: “304”,
    “horsepower”: “150”,
    “weight”: “3433”,
    “acceleration”: “12”,
    “model_year”: “22”,
    “origin”: “usa”,
    “is_deleted”: “0”
}

Post

Adding a Car to the database is quite similar. We need a method in the controller and one in the repo. Here is the controller method:

[HttpPost]
public async Task<ActionResult<Car>> Post([FromBody] Car car)
{
   try
   {
      car = await _carService.Insert(car);
   }
   catch (Exception e)
   {
      return BadRequest(e); 
   }

   return CreatedAtAction(nameof(Get), new { id = car.Id }, car);
}

Look at the attribute in the parameter ([FromBody]. This indicates to the API that the data needed to insert this Car will be in the body of the call. The alternative is FromQuery. You can, in fact, use both in one call.

Note: CreatedAction causes a return code of 201, which is what we want. Here’s the body we’ll insert:

{
        “name”: “chevrolet chevelle malibu”,
        “mpg”: “18”,
        “cylinders”: “8”,
        “displacement”: “307”,
        “horsepower”: “130”,
        “weight”: “3504”,
        “acceleration”: “12”,
        “model_year”: “70”,
        “origin”: “usa”,
        “is_deleted”: “0”
    }

When we click Send this data is sent to the API which returns 201 (created) and in the body of the returned data we see the new id assigned to this car

{
    “id”: 409,
    “name”: “chevrolet chevelle malibu”,
    “mpg”: “18”,
    “cylinders”: “8”,
    “displacement”: “307”,
    “horsepower”: “130”,
    “weight”: “3504”,
    “acceleration”: “12”,
    “model_year”: “70”,
    “origin”: “usa”,
    “is_deleted”: “0”
}

Service Class

Notice that this time, instead of calling the Repo directly, the method in the controller calls into a service class. A service class is a great way to get the logic out of the controller, where it does not belong, without putting it into the repo, where it also does not belong.

Here’s the top of the CarService

public class CarService : ICarService
{
   private readonly ICarRepository _carRepository;

   public CarService(ICarRepository carRepository)
   {
      _carRepository = carRepository;
   }

   public async Task<Car> Insert(Car car)
   {
      var newId = await _carRepository.UpsertAsync(car);
      if (newId > 0)
      {
         car.Id = newId;
      }
      else
      {
         throw new Exception("Failed to insert car");
      }
   return car;
   }

All the logic associated with this insert (e.g., making sure we get back a legitimate id from the repository, etc.) is encapsulated in the service.

This leaves the repository free to just talk to the database,

public async Task<int> UpsertAsync(Car car)
{
using var db = databaseConnectionFactory.GetConnection();
var sql = @"
DECLARE @InsertedRows AS TABLE (Id int);
MERGE INTO Car AS target
USING (SELECT @Id AS Id, @Name AS Name, @Model_Year AS Model_Year, 
@Is_Deleted AS Is_Deleted, @Origin AS origin ) AS source 
ON target.Id = source.Id
WHEN MATCHED THEN 
UPDATE SET 
Name = source.Name, 
Model_Year = source.Model_Year, 
Is_Deleted = source.Is_Deleted,
Origin = source.Origin
WHEN NOT MATCHED THEN
INSERT (Name, Model_Year, Is_Deleted, Origin)
VALUES (source.Name, source.Model_Year, 
source.Is_Deleted, source.Origin)
OUTPUT inserted.Id INTO @InsertedRows
;

SELECT Id FROM @InsertedRows;
";

var newId = await db.QuerySingleOrDefaultAsync<int>(sql, car);
return newId == 0 ? car.Id : newId;
}

Rather than having an insert and an update method, we combine that logic into this upsert method. This is a common idiom for database manipulation.

Note: to make this work, be sure to fill in all the fields for a car (or at least as many as you want to have in the Database.

Delete

As noted earlier, we will implement a soft delete; that is, rather than actually removing the data from the database, we’ll just set the is_deleted column to true. This allows us to reverse the action, and make the row not-deleted by simply changing that value to false.

[HttpDelete(“{id}”)]
public async Task<IActionResult> Delete(int id)
{
try
{
await _carService.Delete(id);
}
catch (Exception e)
{
return BadRequest(e);
}
return NoContent();
}

As you would expect, the endpoint takes an id (the id of the car we want to delete). The controller then hands that off to the service, which calls the repository which, in turn, marks that id as deleted:

public async Task<int> DeleteAsync(int id)
{
   using var db = databaseConnectionFactory.GetConnection();
   var query = "UPDATE car SET Is_Deleted = 1 WHERE Id = @Id";
   return await db.ExecuteAsync(query, new { Id = id });
}

If you are comfortable with SQL none of this will be very surprising. The key walkaway is:

Summary

In this post we saw that endpoints are just URLs with (potentially) data in the body of the request. The controller handles the URL and in our case passes the id or other data to the service. The service handles the (business) logic and then delegates talking to the database to the repository.

Book

This posting is excerpted from my forthcoming book Building APIs with .NET and C# to be released next year by Packt.

About Jesse Liberty

Jesse Liberty has three decades of experience writing and delivering software projects and is the author of 2 dozen books and a couple dozen online courses. His latest book, Building APIs with .NET will be released early in 2025. Liberty is a Senior SW Engineer for CNH and he was a Senior Technical Evangelist for Microsoft, a Distinguished Software Engineer for AT&T, a VP for Information Services for Citibank and a Software Architect for PBS. He is a Microsoft MVP.
This entry was posted in Essentials. Bookmark the permalink.

31 Responses to .NET APIs Part 5 – All the CRUD APIs

  1. DannyDiuro says:

    Услуга вывода из запоя на дому в Улан-Удэ включает полный комплекс мер, направленных на быстрое восстановление организма. При получении вызова нарколог приезжает на дом, проводит тщательный первичный осмотр, измеряет жизненно важные показатели и собирает подробный анамнез. На основе полученных данных формируется индивидуальный план терапии, который может включать инфузионное введение медикаментов с применением современных технологий и оказание психологической поддержки для достижения устойчивой ремиссии.
    Подробнее можно узнать тут – http://vyvod-iz-zapoya-ulan-ude0.ru/narkologiya-vyvod-iz-zapoya-ulan-ude/

  2. Timothyhoami says:

    После обращения в клинику «Основа» наш специалист незамедлительно выезжает для оказания экстренной медицинской помощи в Новосибирске. Процесс установки капельницы предусматривает комплексную диагностику и последующее детоксикационное лечение, что позволяет снизить токсическую нагрузку и стабилизировать состояние пациента. Описание процедуры включает следующие этапы:
    Подробнее можно узнать тут – капельница от запоя в новосибирске

  3. SamuelLoown says:

    Алкогольный запой представляет собой крайне опасное состояние, когда организм переполнен токсинами, а системы внутреннего контроля практически перестают функционировать должным образом. Наркологическая клиника «Трезвая Жизнь» в Екатеринбурге оказывает экстренную помощь при выводе из запоя, используя передовые методы диагностики, детоксикации и поддерживающую терапию. Наша команда опытных врачей-наркологов готова оказать помощь в любое время суток, обеспечивая оперативное вмешательство и строгую анонимность каждого пациента.
    Исследовать вопрос подробнее – вывод из запоя капельница в екатеринбурге

  4. AntonioGidly says:

    Алкогольный запой – это критическое состояние, возникающее при длительном злоупотреблении спиртными напитками, когда организм насыщается токсинами и его жизненно важные системы (сердечно-сосудистая, печёночная, нервная) начинают давать сбой. В такой ситуации необходимо незамедлительное вмешательство специалистов для предотвращения тяжелых осложнений и спасения жизни. Наркологическая клиника «Основа» в Новосибирске предоставляет экстренную помощь с помощью установки капельницы от запоя, позволяющей оперативно вывести токсины из организма, стабилизировать внутренние процессы и создать условия для последующего качественного восстановления.
    Исследовать вопрос подробнее – капельница от запоя клиника новосибирск

  5. AntonioGidly says:

    Алкогольный запой – это критическое состояние, возникающее при длительном злоупотреблении спиртными напитками, когда организм насыщается токсинами и его жизненно важные системы (сердечно-сосудистая, печёночная, нервная) начинают давать сбой. В такой ситуации необходимо незамедлительное вмешательство специалистов для предотвращения тяжелых осложнений и спасения жизни. Наркологическая клиника «Основа» в Новосибирске предоставляет экстренную помощь с помощью установки капельницы от запоя, позволяющей оперативно вывести токсины из организма, стабилизировать внутренние процессы и создать условия для последующего качественного восстановления.
    Разобраться лучше – капельница от запоя клиника

  6. AntonioTib says:

    Специалист уточняет продолжительность запоя, тип употребляемого алкоголя и наличие сопутствующих заболеваний. Такой подробный анализ позволяет подобрать оптимальные методы детоксикации и снизить риск осложнений.
    Детальнее – kapelnica-ot-zapoya-lugansk-lnr0.ru/

  7. DannyDiuro says:

    Когда алкогольный запой угрожает здоровью, оперативное и квалифицированное вмешательство становится жизненно необходимым. В Улан-Удэ специалисты по наркологии оказывают помощь на дому, обеспечивая скорейшую детоксикацию организма, восстановление обменных процессов и стабилизацию работы внутренних органов. Такой подход позволяет пациенту получить комплексное лечение в комфортной домашней обстановке с полным соблюдением конфиденциальности.
    Детальнее – срочный вывод из запоя в улан-удэ

  8. AntonioTib says:

    Специалист уточняет продолжительность запоя, тип употребляемого алкоголя и наличие сопутствующих заболеваний. Такой подробный анализ позволяет подобрать оптимальные методы детоксикации и снизить риск осложнений.
    Узнать больше – капельница от запоя цена луганск

  9. Seymourkib says:

    Алкогольный запой представляет собой крайне опасное состояние, когда организм переполнен токсинами, а системы внутреннего контроля практически перестают функционировать должным образом. Наркологическая клиника «Трезвая Жизнь» в Екатеринбурге оказывает экстренную помощь при выводе из запоя, используя передовые методы диагностики, детоксикации и поддерживающую терапию. Наша команда опытных врачей-наркологов готова оказать помощь в любое время суток, обеспечивая оперативное вмешательство и строгую анонимность каждого пациента.
    Углубиться в тему – наркологический вывод из запоя

  10. SamuelLoown says:

    Алкогольный запой представляет собой крайне опасное состояние, когда организм переполнен токсинами, а системы внутреннего контроля практически перестают функционировать должным образом. Наркологическая клиника «Трезвая Жизнь» в Екатеринбурге оказывает экстренную помощь при выводе из запоя, используя передовые методы диагностики, детоксикации и поддерживающую терапию. Наша команда опытных врачей-наркологов готова оказать помощь в любое время суток, обеспечивая оперативное вмешательство и строгую анонимность каждого пациента.
    Изучить вопрос глубже – вывод из запоя на дому круглосуточно

  11. Dwighthadia says:

    Лечение нарколога на дому в Калининграде проводится по четко отлаженной схеме, включающей несколько последовательных этапов, позволяющих максимально быстро стабилизировать состояние пациента и начать процесс выздоровления.
    Детальнее – вызов нарколога на дом в калининграде

  12. Seymourkib says:

    Назначение
    Получить дополнительные сведения – narkolog-vyvod-iz-zapoya ekaterinburg

  13. 173873 457192It can be tough to write about this subject. I believe you did an excellent job though! Thanks for this! 398775

  14. 1xbet says:

    16764 111955Quite efficiently written story. It is going to be useful to anybody who employess it, including me. Keep up the very good work – canr wait to read far more posts. 884728

  15. Harleybralm says:

    В этой статье-обзоре мы соберем актуальную информацию и интересные факты, которые освещают важные темы. Читатели смогут ознакомиться с различными мнениями и подходами, что позволит им расширить кругозор и глубже понять обсуждаемые вопросы.
    Изучить вопрос глубже – https://mednarkoforum.ru/

  16. Your article helped me a lot, is there any more related content? Thanks!

  17. 460647 33429This is the proper weblog for anybody who hopes to learn about this topic. You know a entire lot its almost tough to argue along (not that I in fact would wantHaHa). You surely put a whole new spin for a subject thats been written about for years. Wonderful stuff, just great! 278644

  18. ftWNb1 says:

    764562 372852This internet web site is often a walk-through for all with the information you wanted concerning this and didnt know who need to. Glimpse here, and you will totally discover it. 232658

  19. The twister then strengthened to EF2 intensity because it moved across Quisenberry Road, where multiple cell properties have been obliterated and a lady was killed in considered one of them.

  20. On March 16, Governor Wolf extended the social distancing measures across your complete state.

  21. India and china are considered to be the primary manufacturing hub for the imitation jewelry.

  22. Hairstyles says:

    Hiya! Quick question that’s entirely off topic. Do you know how to make your site mobile friendly? My website looks weird when browsing from my iphone 4. I’m trying to find a template or plugin that might be able to correct this issue. If you have any recommendations, please share. Appreciate it!

  23. The Mission establishes an addiction recovery program for women.

  24. Back in Florida, Halloween Horror Nights VI via X adopted the formula developed for Halloween Horror Nights V in 1995, rising from 15 nights in 1996 to 19 in 2000.

  25. 押す says:

    Remarks: After seven straight draws, Karpov managed to win sport eight by trapping Korchnoi in a mating internet.

  26. Darth Plagueis was a Muun Dark Lord of the Sith and Darth Sidious’ grasp, first referenced in Star Wars: Episode III – Revenge of the Sith.

  27. Fifteenth Census of the United States : 1930 – Inhabitants Quantity I, United States Census Bureau, p.

  28. Problems are experienced not solely as puzzles however as objects of magnificence.

  29. Steve says:

    Nice article, I always assumed the R in CRUD was for Read but I love using Review as well 😀

  30. Pingback: Dew Drop – January 9, 2024 (#4105) – Morning Dew by Alvin Ashcraft

Leave a Reply to インデックス投資 川崎 Cancel reply

Your email address will not be published. Required fields are marked *