.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.

Unknown's avatar

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. Liberty is a Senior AI Engineer at the University of Pittsburgh Medical Center, and was a Team Lead and Senior Software Engineer for various corporations, 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 21 year Microsoft MVP.
This entry was posted in Essentials. Bookmark the permalink.

2,765 Responses to .NET APIs Part 5 – All the CRUD APIs

  1. Excellent article. Keep writing such kind of info on your site. Im really impressed by your site.

  2. Georgesuete's avatar Georgesuete says:

    https://medmexico.online/# mexico pet pharmacy

  3. Cameron Danz's avatar Cameron Danz says:

    Wow that was strange. I just wrote an incredibly long comment but after I clicked submit my comment didn’t show up. Grrrr… well I’m not writing all that over again. Anyhow, just wanted to say superb blog!

  4. Can I simply just say what a comfort to find somebody who truly knows what they are discussing on the internet. You actually realize how to bring a problem to light and make it important. A lot more people have to look at this and understand this side of your story. It’s surprising you aren’t more popular given that you definitely have the gift.

  5. Hey there, You’ve done a fantastic job. I will definitely digg it and in my view suggest to my friends. I am confident they will be benefited from this web site.

  6. GeorgeIdiob's avatar GeorgeIdiob says:

    farmacias online seguras: farmacia online espaГ±a envГ­o internacional – farmacia online madrid

  7. Currently it appears like WordPress is the best blogging platform out there right now. (from what I’ve read) Is that what you’re using on your blog?

  8. Hey I know this is off topic but I was wondering if you knew of any widgets I could add to my blog that automatically tweet my newest twitter updates. I’ve been looking for a plug-in like this for quite some time and was hoping maybe you would have some experience with something like this. Please let me know if you run into anything. I truly enjoy reading your blog and I look forward to your new updates.

  9. Currently it seems like Expression Engine is the best blogging platform out there right now. (from what I’ve read) Is that what you’re using on your blog?

  10. Excellent pieces. Keep posting such kind of information on your site. Im really impressed by it.

  11. Georgesuete's avatar Georgesuete says:

    https://farmaciaspain.online/# farmacias online seguras

  12. Aw, this was a very good post. Finding the time and actual effort to make a really good article… but what can I say… I hesitate a whole lot and don’t manage to get anything done.

  13. Aw, this was an extremely good post. Finding the time and actual effort to make a good article… but what can I say… I hesitate a whole lot and don’t seem to get nearly anything done.

  14. sa影视's avatar sa影视 says:

    杖与剑的魔剑谭不会魔法照样一路逆袭,战斗过程燃到停不下来高清免费点击观看

  15. Currently it sounds like Movable Type is the top blogging platform out there right now. (from what I’ve read) Is that what you’re using on your blog?

  16. WilliamOrelo's avatar WilliamOrelo says:

    buy cymbalta online: cymbalta – cymbalta for pain

  17. DavidLiz's avatar DavidLiz says:

    https://cymbalta.top/# cymbalta duloxetine

  18. Aw, this was an exceptionally nice post. Spending some time and actual effort to make a very good article… but what can I say… I hesitate a whole lot and never seem to get anything done.

  19. Miriam Peter's avatar Miriam Peter says:

    Hi there, You have performed a great job. I’ll certainly digg it and in my opinion recommend to my friends. I am sure they will be benefited from this website.

  20. Greate post. Keep posting such kind of information on your blog. Im really impressed by your blog.

  21. May I simply say what a comfort to uncover somebody that really knows what they’re talking about on the internet. You certainly know how to bring a problem to light and make it important. More and more people really need to check this out and understand this side of the story. I can’t believe you are not more popular because you surely possess the gift.

  22. Aw, this was a really good post. Taking the time and actual effort to produce a good article… but what can I say… I hesitate a whole lot and never seem to get nearly anything done.

  23. Dian Chass's avatar Dian Chass says:

    Hello there, You’ve done an excellent job. I will certainly digg it and for my part suggest to my friends. I’m confident they will be benefited from this web site.

  24. Hey I know this is off topic but I was wondering if you knew of any widgets I could add to my blog that automatically tweet my newest twitter updates. I’ve been looking for a plug-in like this for quite some time and was hoping maybe you would have some experience with something like this. Please let me know if you run into anything. I truly enjoy reading your blog and I look forward to your new updates.

  25. Hey I know this is off topic but I was wondering if you knew of any widgets I could add to my blog that automatically tweet my newest twitter updates. I’ve been looking for a plug-in like this for quite some time and was hoping maybe you would have some experience with something like this. Please let me know if you run into anything. I truly enjoy reading your blog and I look forward to your new updates.

  26. At this time it seems like Expression Engine is the top blogging platform available right now. (from what I’ve read) Is that what you’re using on your blog?

  27. WilliamOrelo's avatar WilliamOrelo says:

    nootropic Modafinil shipped to USA: smart drugs online US pharmacy – where to buy Modafinil legally in the US

  28. Aw, this was an exceptionally nice post. Finding the time and actual effort to produce a very good article… but what can I say… I hesitate a lot and don’t seem to get anything done.

  29. Wow that was unusual. I just wrote an incredibly long comment but after I clicked submit my comment didn’t show up. Grrrr… well I’m not writing all that over again. Anyway, just wanted to say fantastic blog!

  30. Gregg Pulley's avatar Gregg Pulley says:

    May I simply say what a relief to find someone who actually knows what they’re talking about on the web. You actually realize how to bring a problem to light and make it important. A lot more people ought to look at this and understand this side of your story. It’s surprising you are not more popular given that you most certainly have the gift.

  31. Can I simply say what a comfort to find someone that actually understands what they’re discussing on the web. You definitely know how to bring an issue to light and make it important. More people need to read this and understand this side of the story. I was surprised you are not more popular given that you definitely possess the gift.

  32. Julee Sey's avatar Julee Sey says:

    Excellent article. Keep writing such kind of information on your site. Im really impressed by it.

  33. TimothyAgerb's avatar TimothyAgerb says:

    Обращаем внимание, что таблица носит ознакомительный характер. Точную программу лечения и финальную цену определяет врач после осмотра и необходимых анализов. Врач нарколог бесплатно ответит на все ваши вопросы по услуге вывода из запоя на дому и оформит вызов врача.
    Получить дополнительную информацию – vyvod-iz-zapoya-s-vyezdom

  34. WilliamOrelo's avatar WilliamOrelo says:

    prescription-free Modafinil alternatives: WakeMeds RX – order Provigil without prescription

  35. sa影视's avatar sa影视 says:

    如果你喜欢爱情,这部作品绝对值得剧透。它以1080P的制作水准赢得了业界认可。 免费随时随地

  36. MichaelBoori's avatar MichaelBoori says:

    Веб-сайт oopalkna.space — це елегантний і практичний збірка новинних сайтів України під назвою newsmap.

    На сторінці зібрано перевірені українські джерела.

    Сайт повністю адаптивний під будь-які пристрої, має лаконічний дизайн у сучасному стилі (Tailwind CSS), зручну навігацію та чіткі посилання на джерела.

    Каталог періодично оновлюється, а користувачі можуть пропонувати нові сайти. Відмінний інструмент для оперативного доступу до якісних українських медіа та спеціалізованих ресурсів

  37. Leonila's avatar Leonila says:

    Aw, this was a very good post. Taking the time and actual effort to generate a good article… but what can I say… I hesitate a whole lot and never manage to get nearly anything done.

  38. Trula's avatar Trula says:

    Aw, this was an exceptionally good post. Taking a few minutes and actual effort to produce a top notch article… but what can I say… I hesitate a whole lot and never seem to get nearly anything done.

  39. Loree's avatar Loree says:

    Currently it sounds like BlogEngine is the best blogging platform out there right now. (from what I’ve read) Is that what you are using on your blog?

  40. Nikia's avatar Nikia says:

    Hey I know this is off topic but I was wondering if you knew of any widgets I could add to my blog that automatically tweet my newest twitter updates. I’ve been looking for a plug-in like this for quite some time and was hoping maybe you would have some experience with something like this. Please let me know if you run into anything. I truly enjoy reading your blog and I look forward to your new updates.

  41. Richardweivy's avatar Richardweivy says:

    https://cymbalta.top/# cymbalta medication

  42. Ollie's avatar Ollie says:

    Hey there, You’ve performed an incredible job. I’ll certainly digg it and personally suggest to my friends. I am sure they’ll be benefited from this web site.

  43. Jaymie's avatar Jaymie says:

    Excellent article. Keep writing such kind of info on your page. Im really impressed by it.

  44. Rebbecca's avatar Rebbecca says:

    Right now it seems like WordPress is the preferred blogging platform out there right now. (from what I’ve read) Is that what you’re using on your blog?

  45. Karisa's avatar Karisa says:

    Hey I know this is off topic but I was wondering if you knew of any widgets I could add to my blog that automatically tweet my newest twitter updates. I’ve been looking for a plug-in like this for quite some time and was hoping maybe you would have some experience with something like this. Please let me know if you run into anything. I truly enjoy reading your blog and I look forward to your new updates.

  46. Charlsie's avatar Charlsie says:

    Aw, this was an exceptionally nice post. Taking a few minutes and actual effort to generate a very good article… but what can I say… I hesitate a lot and don’t manage to get nearly anything done.

  47. Ai's avatar Ai says:

    Wow that was unusual. I just wrote an really long comment but after I clicked submit my comment didn’t appear. Grrrr… well I’m not writing all that over again. Anyhow, just wanted to say fantastic blog!

  48. Lauran's avatar Lauran says:

    Hey I know this is off topic but I was wondering if you knew of any widgets I could add to my blog that automatically tweet my newest twitter updates. I’ve been looking for a plug-in like this for quite some time and was hoping maybe you would have some experience with something like this. Please let me know if you run into anything. I truly enjoy reading your blog and I look forward to your new updates.

  49. Zula's avatar Zula says:

    Hi there, You’ve done a fantastic job. I’ll definitely digg it and in my opinion suggest to my friends. I am confident they’ll be benefited from this web site.

  50. Sylvia's avatar Sylvia says:

    Excellent pieces. Keep writing such kind of information on your blog. Im really impressed by your site.

Comments are closed.