10 C# REST API Interview Questions and Answers
Prepare for your next interview with this guide on C# REST API development, featuring common questions and detailed answers.
Prepare for your next interview with this guide on C# REST API development, featuring common questions and detailed answers.
C# is a versatile and powerful programming language, widely used for developing enterprise-level applications. When combined with REST APIs, it enables the creation of robust, scalable, and maintainable web services. REST APIs are essential for enabling communication between different software systems, making them a critical component in modern software development.
This article provides a curated selection of interview questions focused on C# REST API development. By working through these questions and their detailed answers, you will gain a deeper understanding of key concepts and best practices, helping you to confidently tackle technical interviews and demonstrate your expertise.
HTTP methods in RESTful services perform operations on resources identified by URIs. The primary methods are:
Versioning in a REST API maintains backward compatibility while allowing evolution. Strategies include:
https://api.example.com/v1/resource
.https://api.example.com/resource?version=1
.Accept: application/vnd.example.v1+json
.Accept
header to specify the version, e.g., Accept: application/vnd.example.resource+json; version=1
.Each strategy has its pros and cons, such as simplicity versus URL clutter or flexibility versus complexity.
In a C# REST API, handling GET requests involves creating a controller method that interacts with a service to retrieve resources. Attributes like HttpGet and Route define the endpoint and request type.
Example:
using Microsoft.AspNetCore.Mvc; using System.Collections.Generic; namespace MyApi.Controllers { [Route("api/[controller]")] [ApiController] public class ResourcesController : ControllerBase { private readonly IResourceService _resourceService; public ResourcesController(IResourceService resourceService) { _resourceService = resourceService; } [HttpGet] public ActionResult<IEnumerable<Resource>> GetResources() { var resources = _resourceService.GetAllResources(); return Ok(resources); } } }
The ResourcesController class has a route of “api/resources”. The GetResources method, marked with HttpGet, retrieves resources and returns them with an HTTP 200 OK status.
Error handling in a REST API provides clear feedback to clients. In C#, middleware can catch exceptions and return standardized error responses. Key principles include:
Example of error handling in a C# REST API using ASP.NET Core:
public class ErrorHandlingMiddleware { private readonly RequestDelegate _next; public ErrorHandlingMiddleware(RequestDelegate next) { _next = next; } public async Task Invoke(HttpContext context) { try { await _next(context); } catch (Exception ex) { await HandleExceptionAsync(context, ex); } } private static Task HandleExceptionAsync(HttpContext context, Exception exception) { var code = HttpStatusCode.InternalServerError; // 500 if unexpected if (exception is ArgumentException) code = HttpStatusCode.BadRequest; else if (exception is NotFoundException) code = HttpStatusCode.NotFound; var result = JsonConvert.SerializeObject(new { error = exception.Message }); context.Response.ContentType = "application/json"; context.Response.StatusCode = (int)code; return context.Response.WriteAsync(result); } } // In Startup.cs public void Configure(IApplicationBuilder app, IHostingEnvironment env) { app.UseMiddleware<ErrorHandlingMiddleware>(); // other middlewares }
Securing a REST API in C# involves:
Example of implementing JWT authentication in ASP.NET Core:
public void ConfigureServices(IServiceCollection services) { services.AddAuthentication(options => { options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }) .AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, ValidateIssuerSigningKey = true, ValidIssuer = "yourdomain.com", ValidAudience = "yourdomain.com", IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("your_secret_key")) }; }); services.AddAuthorization(); } public void Configure(IApplicationBuilder app, IHostingEnvironment env) { app.UseAuthentication(); app.UseAuthorization(); app.UseMvc(); }
Pagination in a REST API handles large datasets efficiently by allowing clients to request data in smaller chunks. In C#, use query parameters like page
and pageSize
to control the number of records returned.
Example:
[HttpGet] public IActionResult GetItems(int page = 1, int pageSize = 10) { var items = _context.Items .Skip((page - 1) * pageSize) .Take(pageSize) .ToList(); var totalItems = _context.Items.Count(); var totalPages = (int)Math.Ceiling(totalItems / (double)pageSize); var response = new { Page = page, PageSize = pageSize, TotalItems = totalItems, TotalPages = totalPages, Items = items }; return Ok(response); }
The GetItems method uses Skip
and Take
to fetch a subset of data, including metadata like current page and total pages.
To handle POST requests for creating a new resource in a C# REST API, use a controller method that accepts a model, validates input, creates the resource, and returns an appropriate response.
Example:
[ApiController] [Route("api/[controller]")] public class ResourcesController : ControllerBase { [HttpPost] public IActionResult CreateResource([FromBody] ResourceModel resource) { if (resource == null) { return BadRequest("Resource is null."); } // Add logic to save the resource to the database // For example: _context.Resources.Add(resource); // _context.SaveChanges(); return CreatedAtAction(nameof(GetResourceById), new { id = resource.Id }, resource); } [HttpGet("{id}")] public IActionResult GetResourceById(int id) { // Add logic to retrieve the resource by id // For example: var resource = _context.Resources.Find(id); if (resource == null) { return NotFound(); } return Ok(resource); } }
Idempotent operations in REST APIs can be performed multiple times without changing the result beyond the initial application. This ensures APIs behave predictably, even with network issues or retries.
In RESTful services, GET, PUT, DELETE, and HEAD are idempotent. For example, a GET
request will always return the same resource without modifying it, and a DELETE
request will have the same effect whether called once or multiple times.
Idempotency helps build reliable systems, allowing clients to retry requests without unintended side effects, useful in distributed systems with network failures.
Authentication and authorization secure a REST API.
Authentication verifies user identity, while authorization determines resource access.
In C#, use middleware in ASP.NET Core for these processes, often with JWT for authentication and policies or roles for authorization.
Example:
public void ConfigureServices(IServiceCollection services) { services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, ValidateIssuerSigningKey = true, ValidIssuer = Configuration["Jwt:Issuer"], ValidAudience = Configuration["Jwt:Audience"], IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:Key"])) }; }); services.AddAuthorization(options => { options.AddPolicy("AdminOnly", policy => policy.RequireRole("Admin")); }); services.AddControllers(); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); } [Authorize(Policy = "AdminOnly")] [ApiController] [Route("api/[controller]")] public class AdminController : ControllerBase { [HttpGet] public IActionResult Get() { return Ok("This is an admin-only endpoint."); } }
In a REST API, the DELETE method removes a resource identified by a URI. In C#, this can be implemented using ASP.NET Core.
Example:
[HttpDelete("{id}")] public IActionResult DeleteResource(int id) { var resource = _context.Resources.Find(id); if (resource == null) { return NotFound(); } _context.Resources.Remove(resource); _context.SaveChanges(); return NoContent(); }
The DeleteResource method, marked with [HttpDelete]
, takes an id
parameter to find and remove the resource, returning a NoContent
response to indicate successful deletion.