HTTP Methods in ASP.NET Core Web API

HTTP Methods in ASP.NET Core Web API

In this article, I will discuss How to Implement Different HTTP Methods in ASP.NET Core Web API Applications with Examples. Please read our previous article discussing Automapper in ASP.NET Core Web API with Examples. At the end of this article, you will understand the following pointers:

  1. What are HTTP Methods?
  2. Types of HTTP Methods.
  3. What are Safe and Unsafe HTTP Methods?
  4. What are Idempotent Methods in ASP.NET Core Web API?
  5. Idempotency vs Safety
  6. HTTP Methods in ASP.NET Core Web API
  7. Example to Understand ASP.NET Core Web API with HTTP Methods
  8. Best Practices to Use HTTP Methods in ASP.NET Core Web API

What are HTTP Methods?

HTTP (Hypertext Transfer Protocol) methods are a set of request methods used in HTTP to indicate the desired action to be performed on a given resource. These methods tell the server what to do with the resource.

Types of HTTP Methods:

The primary or most commonly used HTTP methods are as follows:

  1. GET: Requests using GET should only retrieve data and should have no other effect.
  2. POST: The HTTP Post Method Sends data to the server. The Content-Type header indicates the type of the request body. This method is often used when submitting form data, uploading a file, or sending a request body in restful services.
  3. PUT: This method replaces all current representations of the target resource with the request payload. That means it is used to update all the properties of the target resource.
  4. PATCH: This HTTP Method is used to update the target resource partially. If you want to update a few properties of the target resource, you need to use the PATCH method instead of the PUT method.
  5. DELETE: Removes the specified resource.
  6. HEAD: This is similar to the GET method but asks for the response without the response body. It is used to obtain metadata about the resource, such as the size of the response body, HTTP headers, etc.
  7. OPTIONS: Describe the communication options for the target resource, i.e., it describes what HTTP methods are supported by the server, what HTTP headers are allowed by the server, etc.

What are Safe and Unsafe HTTP Methods

HTTP methods are classified into two categories based on their impact on the server state: Safe and Unsafe Methods.

Safe HTTP Methods

Safe HTTP methods refer to the HTTP methods that are designed to be read-only, and they do not change the state of the server. These methods are called safe because they don’t modify the server’s data or have any side effects. This safety feature allows them to be repeated (Sending Multiple Requests) without concern, as it does not cause any changes on the server. The primary safe HTTP methods are:

  • GET: Retrieves data from the server. Multiple GET requests to the same resource are expected to return the same result unless the resource’s state has been changed by other means.
  • HEAD: Similar to GET, but it only requests the headers of the response. Like GET, HEAD does not modify the server state and is used to obtain meta-information about the resource, such as its size or headers, without downloading its body.
  • OPTIONS: Used to describe communication options for the target resource, such as which methods are supported and which headers are accepted by the server. It does not modify the server state and is safe to call.
Unsafe HTTP Methods

Unsafe HTTP methods can modify the server’s state, so they should be used cautiously to avoid unintended effects. These methods can create, update, or delete resources and are considered unsafe due to their potential to cause unintended effects. The primary unsafe HTTP methods are:

  • POST: Used to submit data to the server to create a new resource. So, it can change the state of the server by adding a new resource.
  • PUT: It replaces all current representations of the target resource with the request payload. It is used to update a resource on the server.
  • DELETE: It removes the specified resource from the server, changing the state of the server by removing the resource.
  • PATCH: This is the same as the PUT method, but here it will perform partial updates to a resource. PATCH is considered unsafe because it changes the state of the resource.

What are Idempotent Methods in ASP.NET Core Web API

In the context of HTTP and ASP.NET Core Web API, an idempotent method produces the same outcome when called multiple times. Hence, making multiple identical requests has the same effect as making a single request. The idempotent HTTP methods are as follows:

  • GET: Multiple GET requests to the same URL will return the same data, assuming no change in the data between requests.
  • PUT: If a PUT request is made once or multiple times, the outcome is the same. That means if the request body contains the same data, then the response is going to be the same. However, if the PUT operation increments a value, it would not be idempotent.
  • DELETE: Once a resource is deleted, the subsequent DELETE requests to the same resource typically have no effect, as the resource has already been deleted.
  • HEAD: This is similar to GET, but it retrieves the headers instead of the body of the response. Like GET, it is safe to call multiple times which will not change the response.
  • OPTIONS: It is used to describe the communication options for the target resource. Repeated requests do not change the state of the resource.
  • PATCH: A PATCH request can be considered idempotent if it is designed to be so. For example, setting a specific field to a value will have the same effect regardless of how many times the PATCH request is made. However, if the PATCH operation increments a value, it would not be idempotent.

Non-Idempotent HTTP Method

  • POST: Generally used to create a new resource. Since each POST request can create a new resource or change the state, it is not considered idempotent.
Idempotency vs Safety

Although safety and idempotency are related, they are distinct properties of HTTP methods.

  • Safety refers to the method’s ability to be called without causing side effects or changing the server’s state.
  • Idempotency means that multiple identical requests will have the same effect as a single request, regardless of whether the method is safe or unsafe.

For example, GET is Safe and Idempotent, as it does not modify the server state and can be called repeatedly with the same outcome. PUT and DELETE are Unsafe because they modify the server state, but they are Idempotent since repeating these requests has the same effect as making a single request. POST is generally considered both Unsafe and Non-Idempotent because it creates a new resource or changes the server state in a way that repeating the request would typically result in different outcomes (e.g., creating multiple instances of a resource).

HTTP Methods in ASP.NET Core Web API

ASP.NET Core Web API supports various HTTP methods that make it easier to perform Create, Read, Update, and Delete (CRUD) operations and other types of requests (such as HEAD and OPTIONS) over the web. These methods are directly linked to the actions that can be performed on the resources in a RESTful service. The following are primary HTTP methods used in ASP.NET Core Web API, along with their purposes and typical use cases:

HttpGet
  • Purpose: Retrieve information about a resource or a collection of resources.
  • Use Case: Fetching data from the server. It can be a single item by ID or a list of items. It should not change the state of the server.
  • Example: Retrieving a list of users or a single user by ID.
HttpPost
  • Purpose: Create a new resource on the server.
  • Use Case: Submitting data to be processed by the server. For example, creating a new record in the database.
  • Example: Adding a new user to a database.
HttpPut
  • Purpose: Update an existing resource completely. If the resource does not exist, it can create a new resource with a specific ID, depending on the server’s implementation.
  • Use Case: Updating an existing entity with new data. This method replaces the entire entity with the provided version.
  • Example: Updating a user’s information entirely.
HttpPatch
  • Purpose: Partially update an existing resource. It allows sending only the changes rather than the entire resource.
  • Use Case: Applying partial modifications to a resource, such as updating a user’s email without altering other attributes.
  • Example: Changing a user’s email address.
HttpDelete
  • Purpose: Remove a resource from the server.
  • Use Case: Deleting a resource. It should be used to remove an entity from the server.
  • Example: Deleting a user from the database.
HttpOptions
  • Purpose: Clients can use the OPTIONS method to determine which HTTP methods the server supports. This can be useful in RESTful APIs for supporting cross-origin resource sharing (CORS) preflight requests.
  • Use Case: Discover the communication options available for a specific URL or server. Determining which operations (HTTP methods) are supported on a server endpoint.
  • Example: Checking if an endpoint supports PUT requests.
HttpHead
  • Purpose: It retrieves the headers of a resource, which are identical to those of a GET request but without the response body.
  • Use Case: A common use case for the HEAD method is to inspect the content length of a document without downloading it. For example, a client application can use this method to determine if a large file has changed before downloading it, which can save bandwidth and processing time if the file is unchanged. Another example is
  • Example: Checking if a resource exists before downloading it. Retrieving metadata about the resource, such as content type or content length.
Example to Understand ASP.NET Core Web API with HTTP Methods

Let us see an example of Understanding ASP.NET Core Web API with all HTTP methods. In this article, I am just going to show you an example using all the HTTP methods, and from our next article, I will explain each HTTP method in detail, and I will also explain the best way to implement each HTTP Method in ASP.NET Core Web API. Also, I will explain when to use which HTTP Methods in Real-time Applications. First, create the following Product model, which we will use to perform the different operations:

namespace HTTPMethodDemo.Models
{
    public class Product
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public int Price { get; set; }
    }
}

Next, create an API Controller Empty named ProductController and then copy and paste the following code. Here, I am implementing 8 action methods using 7 HTTP methods.

using HTTPMethodDemo.Models;
using Microsoft.AspNetCore.Mvc;

namespace HTTPMethodDemo.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class ProductController : ControllerBase
    {
        private List<Product> products = new List<Product>()
        {
            new Product(){Id = 1, Name ="Laptop", Price = 1000},
            new Product(){Id = 2, Name ="Desktop", Price = 2000}
        };

        // GET requests are used to request data from a specified resource.
        // They should not change the state of the server.
        // GET: api/Product
        [HttpGet]
        public async Task<ActionResult<List<Product>>> GetAllProducts()
        {
            //Fetch all the Products
            return Ok(products);
        }

        // GET: api/Product/1
        [HttpGet("{Id}")]
        public async Task<ActionResult<Product>> GetProductById(int Id)
        {
            var product = products.FirstOrDefault(prd => prd.Id == Id);
            if (product == null)
            {
                return NotFound();
            }

            return Ok(product);
        }

        // POST requests are used to send data to the server to create a new resource.
        // The data is included in the body of the request.
        // POST: api/Items
        [HttpPost]
        public async Task<ActionResult<Product>> CreateProduct(Product product)
        {
            //Add the Product to the Database
            product.Id = 3;
            products.Add(product);

            return CreatedAtAction("GetProductById", new { Id = product.Id }, product);
        }

        // PUT requests are used to send data to a specific resource for update.
        // Unlike POST, PUT is idempotent, meaning multiple identical requests should have the same effect as a single one.
        // PUT: api/Product/1
        [HttpPut("{Id}")]
        public async Task<IActionResult> UpdateProduct(int Id, Product product)
        {
            if (Id != product.Id)
            {
                return BadRequest();
            }

            var existingProduct = products.FirstOrDefault(prd => prd.Id == Id);
            if (existingProduct == null)
            {
                return NotFound();
            }

            //Update the Product Name and Price
            existingProduct.Name = product.Name;
            existingProduct.Price = product.Price;

            //Update the Data into the database

            return NoContent();
        }

        // DELETE requests are used to remove a specific resource identified by a URI.
        // DELETE: api/Product/5
        [HttpDelete("{Id}")]
        public async Task<IActionResult> DeleteProduct(int Id)
        {
            var product = products.FirstOrDefault(prd => prd.Id == Id);
            if (product == null)
            {
                return NotFound();
            }

            //Remove the Product
            products.Remove(product);

            return NoContent();
        }

        // PATCH requests are used for making partial updates to an existing resource.
        // This method allows sending a partial list of changes to the resource, reducing bandwidth and processing time.
        // PATCH: api/Product/5
        [HttpPatch("{Id}")]
        public async Task<IActionResult> PatchProduct(int Id, Product product)
        {
            var existingProduct = products.FirstOrDefault(prd => prd.Id == Id);
            if (existingProduct == null)
            {
                return NotFound();
            }

            //Update only the require Properties, not all
            existingProduct.Name = product.Name;

            //Update the data into the database

            return NoContent();
        }

        // Ensure the HEAD method shares the same routing as the GET method for a resource.
        // HEAD: api/Product/5
        [HttpHead("{Id}")]
        public ActionResult<Product> GetProductHead(int Id)
        {
            var product = products.FirstOrDefault(prd => prd.Id == Id);
            if (product == null)
            {
                return NotFound();
            }
            
            return NoContent(); 
            // Or Ok() with no body content
        }

        // For OPTIONS requests, it's common to return an empty body with a 200 OK status code, with the Allow header specifying the allowed methods.
        // OPTIONS: api/Product
        [HttpOptions]
        public IActionResult Options()
        {
            Response.Headers.Add("Allow", "GET,POST,PUT,PATCH,DELETE,HEAD,OPTIONS");
            return Ok();
        }
    }
}

Now, run the application and test the above endpoints using Swagger, and it should work as expected. 

Best Practices to Use HTTP Methods in ASP.NET Core Web API
  • Use GET for safe actions that do not alter the state of the resource.
  • Use POST to create new resources.
  • Use PUT when the client determines the URI of the newly created or updated resource.
  • Use PATCH for partial updates to a resource when not all attributes need to be specified.
  • Use DELETE to remove resources from the server.
  • Use OPTIONS to check which HTTP methods the server allows.
  • Use HEAD to retrieve the headers of a resource, which are identical to those of a GET request but without the response body.

In the next article, I will discuss How to Implement the HTTP GET Method in the ASP.NET Core Web API Application with Examples. In this article, I explain HTTP Methods in ASP.NET Core Web API with Examples. I hope you enjoy this article, “HTTP Methods in ASP.NET Core Web API.”

Leave a Reply

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