.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

** Note ** Jesse is currently looking for a new position. You can learn more about him at https://jesseliberty.bio Thank you. 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, is now available wherever you buy your books. Liberty 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 13 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. Hello there, You have done a fantastic job. I will definitely digg it and in my opinion recommend to my friends. I’m sure they’ll be benefited from this web site.

  2. KOK下载's avatar KOK下载 says:

    May I simply say what a relief to uncover somebody that really knows what they are talking about on the web. You certainly know how to bring an issue to light and make it important. More and more people should read this and understand this side of your story. I was surprised that you are not more popular because you surely possess the gift.

  3. Excellent article. Keep posting such kind of information on your page. Im really impressed by your blog.

  4. May I simply just say what a relief to uncover someone who genuinely understands what they are talking about on the internet. You certainly realize how to bring a problem to light and make it important. More and more people really need to read this and understand this side of your story. I was surprised that you are not more popular given that you definitely possess the gift.

  5. Aw, this was an incredibly good post. Spending some time and actual effort to generate a great article… but what can I say… I hesitate a whole lot and don’t seem to get anything done.

  6. The other day, while I was at work, my sister stole my iphone and tested to see if it can survive a thirty foot drop, just so she can be a youtube sensation. My apple ipad is now broken and she has 83 views. I know this is totally off topic but I had to share it with someone!

  7. Fobertnap's avatar Fobertnap says:

    The overall feeling and organization of this post make it very comfortable to read and follow, while also keeping the discussion flexible enough for different viewpoints, which is something that always helps create more valuable and interesting conversations online.

  8. xfjr7786's avatar xfjr7786 says:

    Today, while I was at work, my sister stole my iphone and tested to see if it can survive a 40 foot drop, just so she can be a youtube sensation. My apple ipad is now broken and she has 83 views. I know this is completely off topic but I had to share it with someone!

  9. Erin Fairey's avatar Erin Fairey says:

    This is the right site for anyone who really wants to understand this topic. You realize a whole lot its almost hard to argue with you (not that I actually would want to…HaHa). You certainly put a brand new spin on a topic that’s been discussed for many years. Great stuff, just excellent!

  10. Yesterday, while I was at work, my sister stole my iphone and tested to see if it can survive a 25 foot drop, just so she can be a youtube sensation. My apple ipad is now destroyed and she has 83 views. I know this is completely off topic but I had to share it with someone!

  11. 德赢彩票's avatar 德赢彩票 says:

    Just wish to say your article is as astonishing. The clarity in your post is simply great and i can assume you’re an expert on this subject. Fine with your permission let me to grab your feed to keep updated with forthcoming post. Thanks a million and please carry on the gratifying work.

  12. Just wish to say your article is as amazing. The clearness in your post is just nice and i can assume you’re an expert on this subject. Well with your permission let me to grab your RSS feed to keep up to date with forthcoming post. Thanks a million and please keep up the gratifying work.

  13. Fobertnap's avatar Fobertnap says:

    HairNeva operates as a prominent Istanbul-based hair restoration clinic specializing in FUE, DHI, Sapphire FUE, unshaven hair transplants, beard restoration, and modern regenerative treatments. Headed by European Board-certified plastic surgeon Assoc. Prof. Dr. Guncel Ozturk, the clinic integrates individualized treatment strategies, AI-powered hair analysis, all-inclusive medical tourism packages, and extended post-treatment care. HairNeva emphasizes natural outcomes, surgeon-led procedures, patient satisfaction, and full assistance for international patients.
    hair transplant turkey

  14. Robertscals's avatar Robertscals says:

    SildГ©nafil 100 mg sans ordonnance: SildГ©nafil 100 mg sans ordonnance – Viagra prix pharmacie paris

  15. 247。真人's avatar 247。真人 says:

    Just desire to say your article is as surprising. The clearness in your post is just great and i can assume you’re an expert on this subject. Fine with your permission allow me to grab your RSS feed to keep up to date with forthcoming post. Thanks a million and please carry on the rewarding work.

  16. LewisGor's avatar LewisGor says:

    The way this post combines simple explanation, balance, and a smooth conversational style makes it much more pleasant to read, while also helping readers stay interested in the discussion from start to finish without losing focus.

    childrens kids sexual xxx porn pills

  17. Excellent post. Keep posting such kind of information on your site. Im really impressed by your blog.

  18. Excellent post. Keep posting such kind of info on your blog. Im really impressed by your site.

  19. Greate pieces. Keep writing such kind of information on your blog. Im really impressed by it.

  20. 澳博应用's avatar 澳博应用 says:

    At this time it looks like Movable Type is the best blogging platform available right now. (from what I’ve read) Is that what you’re using on your blog?

  21. Currently it appears like Expression Engine is the preferred blogging platform out there right now. (from what I’ve read) Is that what you are using on your blog?

  22. BW注册's avatar BW注册 says:

    At this time it appears like BlogEngine is the preferred blogging platform available right now. (from what I’ve read) Is that what you are using on your blog?

  23. Stephenviaps's avatar Stephenviaps says:

    Reading through this material was quite helpful. You highlighted the most important aspects while keeping the narrative completely neutral, which I always value in online content.

    kids sexual xxx porn onlyfans

  24. rezka-tv.biz's avatar rezka-tv.biz says:

    На нашем сайте представлены мультфильмы всех жанров и направлений – от громких новинок проката до культовых шедевров, к которым хочется возвращаться. Мы разместили в единой библиотеке тысячи фильмов, сериалов и мультфильмов, чтобы каждый пользователь мог легко подобрать интересный контент для отдыха. Основная часть каталога представлена в качестве HD, а количество рекламы сведено к минимуму, чтобы просмотр оставался комфортным. Мы постоянно обновляем библиотеку, расширяя выбор актуального контента, о которых говорят зрители по всему миру.

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

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

  26. At this time it sounds like Drupal is the top blogging platform out there right now. (from what I’ve read) Is that what you are using on your blog?

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

  28. Right now it appears like Expression Engine is the top blogging platform available right now. (from what I’ve read) Is that what you are using on your blog?

  29. 维基注册's avatar 维基注册 says:

    Hi there, You have performed a great job. I will definitely digg it and in my opinion recommend to my friends. I’m confident they’ll be benefited from this web site.

  30. 乐投平台's avatar 乐投平台 says:

    Hello there, You’ve performed an excellent job. I’ll certainly digg it and personally suggest to my friends. I’m confident they’ll be benefited from this site.

  31. OLanepiliA's avatar OLanepiliA says:

    This is a fantastic breakdown of the subject. You managed to capture all the essential details in a very logical sequence without any unnecessary fluff or overwhelming jargon.

    Xxx video onlyfans sex video site

  32. Richardkig's avatar Richardkig says:

    online mexican pharmacy: purple pharmacy online – mexican online mail order pharmacy

  33. Hey there, You’ve performed a great job. I’ll definitely digg it and for my part suggest to my friends. I am confident they will be benefited from this website.

  34. Robertscals's avatar Robertscals says:

    mexican rx pharm: mexi pharmacy – phentermine in mexico pharmacy

  35. Jamesmug's avatar Jamesmug says:

    Macksood Urology Macksood Urology Urological Services Macksood Urology

  36. Gordondub's avatar Gordondub says:

    online ed drugs: Macksood Urology – buy ed pills

  37. JamesEsoli's avatar JamesEsoli says:

    п»їed pills online Dr. Macksood Urologist

  38. DichaelAlono's avatar DichaelAlono says:

    The overall flow of this post works really well because each idea connects smoothly and helps keep the reader focused throughout the discussion.

    Watch sexual porno video xxx sex adults site

  39. Jamesmug's avatar Jamesmug says:

    ed doctor online Macksood Urology ed online treatment

  40. Jamesmug's avatar Jamesmug says:

    generic ed meds online Macksood Urology order ed meds online

  41. Jamesmug's avatar Jamesmug says:

    cheap ed medication Dr. Macksood Urologist best ed pills online

  42. Russelltix's avatar Russelltix says:

    buy Levitra over the counter https://macksoodurology.com/ed-medications/levitra-vardenafil/ boner pills online

  43. Hello there, You’ve done a great job. I’ll certainly digg it and in my opinion recommend to my friends. I am confident they’ll be benefited from this website.

  44. Hi there, You’ve performed a great job. I will certainly digg it and in my view suggest to my friends. I am confident they’ll be benefited from this web site.

  45. EarnestCor's avatar EarnestCor says:

    This article is a wonderful example of how to present facts clearly. I really appreciate the neutral tone and the simple formatting that makes the entire read so engaging and simple.

    Casinos online cuenta rut

  46. Russelltix's avatar Russelltix says:

    Sildenafil Citrate Tablets 100mg https://macksoodurology.com/ed-medications/cialis-tadalafil/ buying ed pills online

Leave a Reply

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