Skip to content

What is Web API in ASP.NET Core and Why Do We Use It?

An ASP.NET Core MVC application returns HTML pages: the server builds the page and the browser shows it. But today the same data is needed by many different clients: a React or Angular website, an Android app, an iPhone app, another company's system, a Power BI report. None of them want an HTML page. They want just the data.

That's what a Web API does.

A Web API is an application that exposes data and operations over HTTP, usually as JSON, so that any kind of client can use them. Instead of "show me the products page", a client asks "give me the list of products", and gets back data it can display or process however it likes.

A real-life example

Think of a restaurant. You (the client) don't walk into the kitchen and cook. You read the menu (the list of things you can ask for), place an order with the waiter (the API), and the waiter brings back your food (the data). You don't need to know how the kitchen works, whether it uses gas or electricity, or who the chef is. And the same kitchen can serve dine-in customers, take-away orders and delivery apps.

A Web API works the same way:

  • The menu is the list of API endpoints: GET /api/products, POST /api/orders...
  • The order is an HTTP request.
  • The food is the HTTP response, usually JSON.
  • The kitchen is your business logic and database, hidden from the client.

MVC vs Web API: what's the difference?

MVC application                               Web API
---------------                               -------
Browser  ── GET /Products ──►  Server         Any client ── GET /api/products ──►  Server
Browser  ◄── full HTML page ──  Server         Any client ◄── JSON data ─────────  Server

<html><body><table>                          [{"id":1,"name":"Wireless Mouse","price":799},
  <tr><td>Wireless Mouse</td>...                {"id":2,"name":"Mechanical Keyboard","price":3499}]
PointMVC controllerWeb API controller
ReturnsHTML views (return View())Data: JSON or XML (return Ok(data))
Base classController (has view support)ControllerBase (no view support needed)
AttributeNone required[ApiController]
ClientA web browser showing pagesAny app: SPA, mobile, desktop, another server
RoutingUsually conventional ({controller}/{action})Attribute routing ([Route("api/[controller]")])
ErrorsError pageHTTP status code + JSON error (ProblemDetails)

In ASP.NET Core, MVC and Web API are one framework. The same project can have MVC controllers that return pages and API controllers that return JSON. (In the old ASP.NET on .NET Framework, they were two separate frameworks.)

Why do we use Web API?

  1. One backend, many clients. Write the business logic and database code once; the website, Android app, iOS app and partner systems all use the same API.
  2. Modern front ends need it. React, Angular, Vue and Blazor WebAssembly apps run in the browser and fetch their data from an API.
  3. Integration between systems. Payment gateways, shipping companies, SMS providers and ERP systems all communicate through APIs. Your app can offer its own API to partners in the same way.
  4. Separation of concerns. Front-end and back-end teams work independently, agreeing only on the API "contract": URLs, request and response shapes.
  5. Lightweight and fast. JSON is small compared with full HTML pages, which matters for mobile networks.
  6. Platform independent. Any language that can make an HTTP request can call it: JavaScript, Python, Java, Kotlin, Swift, C#.
  7. Scalability and microservices. Each service (orders, payments, inventory) can be a separate API that is deployed and scaled on its own.

REST: the style most Web APIs follow

Most Web APIs are REST (Representational State Transfer) APIs. REST is a set of simple rules that make APIs predictable:

  • Everything is a resource with a URL. Use nouns, not verbs: /api/products, /api/products/2, /api/customers/7/orders.
  • The HTTP method says what to do with the resource (see the table below).
  • Stateless. Each request carries everything the server needs (for example a token). The server doesn't remember previous requests.
  • Standard status codes tell the client what happened.
  • Representations. The resource is sent in a format such as JSON.

HTTP methods (verbs)

MethodPurposeExampleTypical success code
GETRead dataGET /api/products/2200 OK
POSTCreate a new resourcePOST /api/products201 Created
PUTReplace a whole resourcePUT /api/products/2200 OK or 204 No Content
PATCHChange part of a resourcePATCH /api/products/2200 OK or 204 No Content
DELETERemove a resourceDELETE /api/products/2204 No Content

The next two lessons compare the methods that confuse people most: GET vs POST and PUT vs PATCH.

HTTP status codes you'll use every day

CodeMeaningASP.NET Core helper
200 OKSuccess, with data in the bodyOk(data)
201 CreatedA new resource was createdCreatedAtAction(...)
204 No ContentSuccess, nothing to returnNoContent()
400 Bad RequestThe request data is invalidBadRequest() (automatic with [ApiController])
401 UnauthorizedNot logged in / no valid tokenUnauthorized()
403 ForbiddenLogged in, but not allowedForbid()
404 Not FoundThe resource doesn't existNotFound()
409 ConflictConflicts with the current state (e.g. duplicate)Conflict()
415 Unsupported Media TypeThe body format isn't acceptedAutomatic
500 Internal Server ErrorA bug or failure on the serverUnhandled exceptions

Building a Web API in ASP.NET Core

Let's build a small Products API for an electronics shop. You can create a new project with dotnet new webapi -n ShopApi --use-controllers, or add API controllers to an existing MVC project. All the responses shown in this lesson series were captured by running this exact API.

Program.cs

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers();                  // API controllers (no views needed)
builder.Services.AddSingleton<ProductStore>();      // our in-memory "database"

var app = builder.Build();
app.MapControllers();                               // map attribute-routed controllers
app.Run();

The model

public class Product
{
    public int Id { get; set; }
    public string Name { get; set; } = "";
    public string Category { get; set; } = "";
    public decimal Price { get; set; }
    public int Stock { get; set; }
}

To keep the example simple, ProductStore is a small class holding a List<Product> with three sample products (a Wireless Mouse, a Mechanical Keyboard and a 27-inch Monitor). In a real project this would be a repository using Entity Framework Core or Dapper.

The API controller

using Microsoft.AspNetCore.Mvc;

[ApiController]
[Route("api/[controller]")]                         // base URL: /api/products
public class ProductsController : ControllerBase
{
    private readonly ProductStore _store;
    public ProductsController(ProductStore store) => _store = store;

    // GET api/products
    [HttpGet]
    public IActionResult GetAll() => Ok(_store.GetAll());

    // GET api/products/2
    [HttpGet("{id:int}")]
    public IActionResult GetById(int id)
    {
        var product = _store.Find(id);
        return product is null ? NotFound() : Ok(product);
    }

    // DELETE api/products/2
    [HttpDelete("{id:int}")]
    public IActionResult Delete(int id) => _store.Remove(id) ? NoContent() : NotFound();
}

The POST, PUT and PATCH actions of this controller are explained in the next two lessons.

Calling the API

A GET request can be tested directly in the browser by opening http://localhost:5288/api/products:

GET /api/products
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

[{"id":1,"name":"Wireless Mouse","category":"Accessories","price":799,"stock":120},
 {"id":2,"name":"Mechanical Keyboard","category":"Accessories","price":3499,"stock":45},
 {"id":3,"name":"27-inch Monitor","category":"Displays","price":15999,"stock":18}]
GET /api/products/99 (does not exist)
HTTP/1.1 404 Not Found
Content-Type: application/problem+json; charset=utf-8

{"type":"https://tools.ietf.org/html/rfc9110#section-15.5.5","title":"Not Found","status":404,"traceId":"00-d309d2ab..."}

Notice two things:

  • We returned C# objects, and ASP.NET Core automatically converted them to JSON, with camelCase property names (Name became "name").
  • For the 404, [ApiController] automatically produced a standard ProblemDetails JSON error, so every client gets errors in the same format.

What does [ApiController] do?

The [ApiController] attribute switches on behaviours that every good API needs:

  • Automatic model validation: if the request data breaks a validation rule ([Required], [Range]...), the action doesn't even run; the client gets a 400 Bad Request listing every error. No more if (!ModelState.IsValid) in each action.
  • Binding source inference: complex types are read from the request body automatically ([FromBody]), and simple types from the route or query string.
  • ProblemDetails responses for error status codes.
  • Attribute routing is required, which keeps API URLs explicit.

How to test a Web API

ToolGood for
BrowserQuick GET requests only
Swagger UI / OpenAPIInteractive documentation page where you can try every endpoint
Postman, InsomniaAny request, with saved collections and environments
.http files in Visual Studio / VS CodeRequests saved as text next to your code
curlCommand line and scripts
### ShopApi.http (Visual Studio / VS Code REST client)
GET http://localhost:5288/api/products/2

###
POST http://localhost:5288/api/products
Content-Type: application/json

{ "name": "USB-C Hub", "category": "Accessories", "price": 1899, "stock": 60 }

Interview questions

1. What is Web API?

A Web API is a service that exposes data and operations over HTTP, usually as JSON, so that any client (browsers, mobile apps, other servers) can use it. In ASP.NET Core it is built with controllers that inherit from ControllerBase and use [ApiController].

2. What is the difference between MVC and Web API?

MVC controllers return HTML views for browsers; Web API controllers return data (JSON/XML) for any client. In ASP.NET Core both are part of one framework: MVC controllers inherit Controller, API controllers inherit ControllerBase.

3. What is REST?

An architectural style in which resources are identified by URLs, HTTP methods describe the operation (GET, POST, PUT, PATCH, DELETE), communication is stateless, and standard status codes describe the result.

4. Why use ControllerBase instead of Controller for APIs?

Controller adds view support (View(), ViewBag, TempData) that an API doesn't need. ControllerBase has everything for APIs: Ok, NotFound, CreatedAtAction and model binding.

5. What does [ApiController] do?

It enables automatic 400 responses for invalid models, infers binding sources ([FromBody] for complex types), returns ProblemDetails for errors, and requires attribute routing.

6. What is the difference between 401 and 403?

401 Unauthorized means the client is not authenticated (no or invalid credentials). 403 Forbidden means the client is authenticated but doesn't have permission for this resource.

Summary

  • A Web API exposes data and operations over HTTP, usually as JSON, for any kind of client.
  • We use it so one backend can serve websites, mobile apps, SPAs and partner systems.
  • REST APIs use resource URLs, HTTP methods, stateless requests and standard status codes.
  • In ASP.NET Core, API controllers inherit ControllerBase, use [ApiController] and attribute routing, and return results like Ok(), NotFound() and CreatedAtAction().
  • Objects are serialized to JSON automatically, and validation errors become 400 responses automatically.

Next: GET vs POST in Web API.