ASP.NET Core Web API documentation web application
This document provides an overview of building a RESTful API with ASP.NET Core Web API. It covers topics like ASP.NET Core fundamentals, creating an API controller, routing, HTTP methods, dependency injection, repositories, action methods, and status codes. The goal is to demonstrate how to structure an API project in ASP.NET Core and add functionality to controllers through techniques like routing, dependency injection, and returning appropriate status codes.
COVERED TOPICS ASP.NETCore & ASP.NET Core API Creating an API from scratch Dependency injection Entity Framework Core Logging Content Negotiation Tooling And much more!
ASP.NET CORE “ASP.NET Coreis a new open-source and cross-platform framework for building modern cloud based internet connected applications, such as web apps, IoT apps and mobile backends.” source: https://docs.microsoft.com/en-us/aspnet/core
11.
ASP.NET CORE Builton top of .NET Core Cross-platform Windows, Mac & Linux Not tied to original .NET framework
12.
WHAT DOES ASP.NETCORE BRING US? Unification between MVC and Web API Dependency Injection Modular HTTP request pipeline Based on NuGet Cloud-ready IIS or self-host Open source Cross-platform New tooling Better integration of client-side frameworks Command-line support
13.
MAIN NEW FEATURESIN ASP.NET CORE Startup class Dependency Injection Middleware New type of configuration Hosting Identity
BASE CONCEPTS INASP.NET CORE An ASP.NET Core app is a console app that creates a web server in its Main method MVC will get added soon!
24.
STARTUP CLASS TheUseStartup method on WebHostBuilder specifies the Startup class for your app Use to define request handing pipeline and services for the app are configured Contains 2 important methods Configure: used to configure the middleware in the request pipeline ConfigureServices: defines services that we’ll be using in the app MVC, EF, Logging…
STARTUP CLASS Note:this is dependency injection at work public class Startup { public void ConfigureServices(IServiceCollection services) { } public void Configure(IApplicationBuilder app) { } }
27.
SERVICES IN ASP.NETCORE MVC Service is a component for usage in an application Are injected and made available through DI ASP.NET Core comes with built-in DI container Can be replaced if needed Supports more loosely-coupled architecture Components are available throughout the application using this container Typically, things like logging are injected this way
MIDDLEWARE Request pipelinegets composed using middleware ASP.NET Core middleware performs asynchronous logic on an HttpContext and then either invokes the next middleware in the sequence or terminates the request directly Typically used by adding a reference to a NuGet package Followed by calling UseXXX() on IApplicationBuilding in the Configure method
31.
MIDDLEWARE ASP.NET Corecomes with lots of built-in middleware Static file support Routing Authentication MVC… You can also write your own middleware
32.
REQUEST PIPELINE Requestsare passed from delegate to delegate Can be short-circuited Static files (MVC) Keeps load on server lower
33.
CONFIGURE Ex: UseMvc Adds routing Configures MVC as default handler Parameters are injected using DI
34.
ORDERING MIDDLEWARE COMPONENTS Order in which they are added will decide how they are called! Critical for security, performance and even functionality Default order Exception/error handling Static file server Authentication MVC public void Configure(IApplicationBuilder app) { app.UseExceptionHandler("/Home/Error"); // Call first to catch exceptions // thrown in the following middleware. app.UseStaticFiles(); // Return static files and end pipeline. app.UseIdentity(); // Authenticate before you access // secure resources. app.UseMvcWithDefaultRoute(); // Add MVC to the request pipeline. }
35.
THE STARTUP OFTHE APPLICATION Application starting Startup class ConfigureServices method Configure method Ready for requests
CREATING AN APICONTROLLER API controller == MVC controller that gives access to data without HTML Data delivery is most often done using REST Representational State Transfer REST is based on HTTP verbs and URLs/resources HTTP verb specifies what we want to do Resource represent what we want to use, which objects Format is JSON (preferred) or XML
41.
A VERY SIMPLECONTROLLER Similar to controllers in plain ASP.NET Core MVC Base ApiController is no more All is now in one class: Controller You can (and should) now have mixed classes public class PieController : Controller { ... }
42.
A VERY SIMPLEACTION METHOD public class PieController : Controller { public JsonResult Get() { var pies = new List<Pie>() { ... }; return new JsonResult(pies); } }
ROUTING Routing willallow us to match the request to the action method on the Controller 2 options exist Convention-based routing Useful for MVC applications Similar to “old” model Attribute-based routing More natural fit for APIs
46.
WORKING WITH THEROUTE Convention is starting the route with api, followed by name of the controller Can be reached using /api/pie
47.
HTTP METHODS Routesare combined with HTTP methods Used to indicate which action we want to do Each will have a result, a payload Response code is used to report on the outcome of the operation
48.
HTTP METHODS Verb MethodResult GET /api/pie Gets collection of all pies GET /api/pie/1 Gets specific pie POST /api/pie Contains data to create a new pie instance, will return saved data PUT /api/pie Contains changed data to update an existing pie instance DELETE /api/pie/1 Deletes certain pie
DEPENDENCY INJECTION Typeof inversion of control (IoC) Another class is responsible for obtaining the required dependency Results in more loose coupling Container handles instantiation as well as lifetime of objects Built-in into ASP.NET Core Can be replaced with other container if needed
DEPENDENCY INJECTION INCONTROLLER Constructor injection: adds dependencies into constructor parameters public class PieController : Controller { private readonly ISomethingService _something; public PieController(ISomethingService something) { _something = something; } }
60.
“ ” USE A REPOSITORYTO SEPARATE THE LOGIC THAT RETRIEVES THE DATA AND MAPS IT TO THE ENTITY MODEL FROM THE BUSINESS LOGIC THAT ACTS ON THE MODEL. THE BUSINESS LOGIC SHOULD BE AGNOSTIC TO THE TYPE OF DATA THAT COMPRISES THE DATA SOURCE LAYER
61.
THE REPOSITORY public classPieRepository : IPieRepository { private List<Pie> _pies; public PieRepository() { _pies = new List<Pie>() { ... }; } public IEnumerable<Pie> Pies => _pies; }
62.
REGISTERING THE REPOSITORY publicvoid ConfigureServices(IServiceCollection services) { services.AddSingleton<IPieRepository, PieRepository>(); }
ACTION METHODS Actionmethods need to be declared with attribute that specifies the HTTP method Available attributes HttpGet HttpPost HttpPut HttpDelete HttpPatch HttpHead AcceptVerbs: for multiple verbs on one method
66.
ACTION METHODS Wecan pass values (routing fragment) Can be reached by combining the route with the parameter /api/pie/{id} Routes in general don’t contain an action segment Action name isn’t part of the URL to reach an action method HTTP method is used to differentiate between them
67.
ACTION RESULTS APIaction methods don’t rely on ViewResult Instead, return data MVC will make sure they get returned in a correct format By default JSON It’s possible to change this, even from the client Media Type formatting is applied here
68.
STATUS CODES Statuscode are part of the response from the API Used for information: Whether or not the request succeeded Why did it fail
69.
STATUS CODES MVCis good at knowing what to return If we return null, it’ll return 204 – No Content We can override this by returning a different IActionResult NotFound leads to 404 Ok just sends the object to the client and returns 200
70.
MOST IMPORTANT STATUSCODES 20X: Success 200: OK 201: Created 204: No content 40X: Client error 400: Bad request 403: Forbidden 404: Not found 50X: Server error 500: Internal server error
LOGGING IN ASP.NETCORE Built-in into ASP.NET Core Available as middleware ILogger Provider-based model External providers can be added if needed
CONTENT FORMATTING MVChas to work out which data format it should return Basically, which encoding to use Can be influenced by the client request Content format depends on Format(s) accepted by client Format(s) that can be produced Content policy specified by the action Type returned by the action Can be hard to figure out In most cases, the default will do
82.
DEFAULT CONTENT POLICY Easiest situation: client and action method define no restrictions on the format that can be used If method returns string, string is returned to client, content-type header is set to text/plain All other data types are returned as JSON, content-type is set to application/json Strings aren’t returned as JSON because of possible issues Double quoted strings: “”Hello world”” An int is simply returned as “2”
CONTENT NEGOTIATION Clientswill typically include an Accept header Specifies possible accepted formats (MIME types) Browser will send Accept: text/html,application/xhtml +xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Prefers HTML and XHTML, can accept XML and Webp Q indicated preference (xml is less preferred) */* indicated that all will work But only for 0.8
85.
CHANGING THE ACCEPTHEADER If we ask the API for XML… Headers Accept="application/xml" We’ll get back json… (Thank you MVC) MVC doesn’t know about XML at this point
86.
XML PLEASE Requiresextra package to be included And as always, some configuration change in the Startup class
OVERRIDING THE ACTIONDATA FORMAT We can specify the data format on the action method itself Produces is filter Changes the content type Argument is the returned data format
89.
PASSING THE DATAFORMAT USING THE ROUTE OR THE QUERY STRING ACCEPT header can’t always be controlled from client Data format can therefore also be specified through route or query string to reach an action We can define a shorthand in the Startup class xml can now be used to refer to application/xml
90.
PASSING THE DATAFORMAT USING THE ROUTE OR THE QUERY STRING On the action, we now need to add the FormatFilter Upon receiving the shorthand (xml), the mapped type from the Startup is retrieved Route can now also include the format (optional) If combined with Produces and other type is requested, 404 is returned
91.
REAL CONTENT NEGOTIATION RespectBrowserAcceptHeader: if true, accept header will be fully respected ReturnHttpNotAcceptable: if no format can be found, 406 – Not Acceptable is returned
VERSIONING AN API Something that’s often forgotten by developers… Versioning is required Clients evolve, API needs to follow as well Old versions often still required Many ways exist URI versioning Header versioning Accept-headers versioning …
95.
VERSIONING AN API Open-source package microsoft.aspnetcore.mvc.versioning Supports ASP.NET Web API ASP.NET Web API with oData ASP.NET Core Added using services.AddApiVersioning();
96.
VERSIONING USING QUERYSTRINGPARAMETER VERSIONING namespace My.Services.V1 { [ApiVersion("1.0")] public class HelloWorldController : Controller { public string Get() => "Hello world v1.0!"; } } namespace My.Services.V2 { [ApiVersion("2.0")] public class HelloWorldController : Controller { public string Get() => "Hello world v2.0!"; } }
97.
VERSIONING USING URLPATH SEGMENT [ApiVersion("1.0")] [Route("api/v{version:apiVersion}/[controller]")] public class HelloWorldController : Controller { public string Get() => "Hello world!"; } [ApiVersion("2.0")] [ApiVersion("3.0")] [Route("api/v{version:apiVersion}/helloworld")] public class HelloWorld2Controller : Controller { [HttpGet] public string Get() => "Hello world v2!"; [HttpGet, MapToApiVersion( "3.0" )] public string GetV3() => "Hello world v3!"; }
98.
VERSIONING USING HEADER publicvoid ConfigureServices(IServiceCollection services) { services.AddMvc(); services.AddApiVersioning(o => o.ApiVersionReader = new HeaderApiVersionReader("api-version")); }
DEPLOYING TO AZURE Account via portal.azure.com Create an Azure App Service SQL Server database if using a DB Visual Studio Publish from Solution Explorer