REST API Interview Questions for ASP.NET Core Developers

If you're prepping for a .NET backend interview, chances are the panel will spend at least half the conversation on REST API design and ASP.NET Core specifics. Interviewers rarely want textbook definitions — they want to know if you've actually built and debugged this stuff. This guide walks through 50 questions grouped by theme, with answers written the way you'd actually say them out loud, plus code where it clarifies more than prose would.

I've split the questions into REST theory, HTTP mechanics, ASP.NET Core implementation, security, performance, and testing, because that's roughly how a real interview flows — starting broad, then narrowing into your specific stack experience.

REST Fundamentals

1. What is REST, in your own words?

REST (Representational State Transfer) is an architectural style for designing networked APIs around resources, identified by URIs, that clients manipulate using standard HTTP methods. It's a set of constraints, not a protocol or a standard.

2. What are the core constraints of a RESTful system?

Statelessness, a uniform interface, client-server separation, cacheability, a layered system, and optionally code-on-demand. An API that violates most of these is still "REST-ish" in practice — plenty of production APIs bend the rules.

3. What does "statelessness" actually mean for an API?

Each request must contain all the information the server needs to process it. The server doesn't store client session state between requests. That's why JWTs and API keys are sent on every call instead of relying on server-side session cookies.

4. Is REST a protocol?

No. REST is an architectural style built on top of HTTP. HTTP is the protocol; REST is how you use it consistently.

5. What's the difference between REST and SOAP?

SOAP is a strict protocol with its own envelope format (XML) and built-in standards for security and transactions (WS-Security, WS-AtomicTransaction). REST is lighter, typically uses JSON, and leans on HTTP itself for semantics. SOAP still shows up in older enterprise and banking integrations; most new .NET APIs are REST or gRPC.

6. What is a resource in REST terms?

Anything you can name and address with a URI — a customer, an order, a collection of orders. /api/orders/42 addresses one order; /api/orders addresses the collection.

7. What is HATEOAS and do real APIs use it?

Hypermedia As The Engine Of Application State means responses include links describing what actions are available next, so clients don't hardcode URL structures. It's the most theoretically "pure" REST constraint and also the least implemented in practice — most public APIs, including a lot of what Microsoft ships, skip it because the tooling and client complexity rarely pay off for typical CRUD APIs.

8. What's the difference between a Web API and a REST API?

In casual dev conversation these terms get used interchangeably, but strictly speaking a Web API is any HTTP-based API — it doesn't have to follow REST constraints. A REST API is a Web API that follows REST's architectural rules. ASP.NET Core's "Web API" project template can be used to build a fully RESTful API or a looser RPC-style one; the framework doesn't enforce REST for you.

9. What is content negotiation?

The process by which client and server agree on the representation format of a resource, usually via the Accept and Content-Type headers. ASP.NET Core's output formatters handle this automatically for JSON by default, and you can add XML formatters if a client requests them.

10. What's the difference between PUT and PATCH in REST terms?

PUT replaces the entire resource representation; PATCH applies a partial update. If a client sends a PUT with only two fields, a strict implementation should treat the missing fields as being reset to their defaults or null — that trips up a lot of developers who use PUT like PATCH out of habit.

HTTP Verbs, Status Codes, and Idempotency

11. What does "idempotent" mean, and which HTTP methods are idempotent?

An idempotent operation produces the same server state no matter how many times it's repeated. GET, PUT, DELETE, HEAD, and OPTIONS are idempotent by definition. POST is not — calling it twice can create two resources. This matters a lot in retry logic: if a client times out and retries a POST, it can double-create a record unless you add an idempotency key.

12. How would you implement idempotency for a POST endpoint, like a payment API?

The common pattern is an Idempotency-Key header the client generates once per logical operation. The server stores the key alongside the result of the first successful request, and if the same key arrives again, it returns the cached response instead of reprocessing.

csharp
[HttpPost]
public async Task<IActionResult> CreatePayment(
[FromHeader(Name = "Idempotency-Key")] string idempotencyKey,
[FromBody] PaymentRequest request)
{
var existing = await _idempotencyStore.GetAsync(idempotencyKey);
if (existing is not null)
return StatusCode(existing.StatusCode, existing.Body);
var result = await _paymentService.ProcessAsync(request);
await _idempotencyStore.SaveAsync(idempotencyKey, StatusCodes.Status201Created, result);
return CreatedAtAction(nameof(GetPayment), new { id = result.Id }, result);
}

The store here could be a Redis cache with a reasonable TTL — you don't want to keep every idempotency key forever, just long enough to cover realistic retry windows.

13. What's the difference between 401 and 403?

401 Unauthorized means the request lacks valid authentication — the server doesn't know who you are. 403 Forbidden means the server knows who you are but you don't have permission for that resource. A surprising number of APIs get this backwards.

14. When should an API return 422 instead of 400?

400 Bad Request generally signals malformed syntax — invalid JSON, missing required fields. 422 Unprocessable Entity signals the request is well-formed but semantically invalid, like a valid JSON payload that fails a business rule. ASP.NET Core's built-in model validation returns 400 by default for both cases, so if you want the 422 distinction you typically implement it yourself.

15. What's the difference between 200 and 201?

200 OK is a generic success. 201 Created specifically means a new resource was created, and the response should include a Location header pointing to the new resource. CreatedAtAction in ASP.NET Core generates that header for you.

16. What is a 204 response used for?

204 No Content indicates success with nothing to return in the body — common for DELETE endpoints or PUT updates where the client doesn't need the updated resource echoed back.

17. What's the difference between 502 and 503?

502 Bad Gateway means an upstream server (behind a proxy or gateway) returned an invalid response. 503 Service Unavailable means the server itself is temporarily unable to handle the request, often due to overload or maintenance.

18. Should DELETE be idempotent even if the resource is already gone?

Yes, by spec. Deleting something that doesn't exist should still return a success-ish status (204 or 404, depending on your team's convention) rather than an error, because calling DELETE twice shouldn't be treated as a failure the second time.

19. What's the difference between GET with a query string and POST for search operations?

GET with query parameters is cacheable, bookmarkable, and idempotent, but URLs have practical length limits and query strings appear in server logs. POST is used for complex search bodies (large filter objects) where you don't want that data in the URL, accepting that you lose caching and idempotency guarantees.

20. What does "safe" mean for an HTTP method, and how does it differ from idempotent?

A safe method doesn't change server state at all — GET and HEAD are safe. Idempotent methods can change state, just not differently on repeat. All safe methods are idempotent, but not all idempotent methods are safe (PUT and DELETE change state but are still idempotent).

ASP.NET Core Routing, Controllers, and Minimal APIs

21. What's the difference between conventional routing and attribute routing?

Conventional routing defines URL patterns centrally (mostly used in MVC views). Attribute routing puts route templates directly on controllers and actions via [Route], [HttpGet], etc. Web APIs in ASP.NET Core almost always use attribute routing because it keeps the URL structure next to the code that handles it.

22. What is model binding, and how does ASP.NET Core know where to pull data from?

Model binding maps incoming request data — route values, query string, headers, body — onto action method parameters. Attributes like [FromRoute], [FromQuery], [FromBody], and [FromHeader] make the source explicit; without them, the framework infers based on parameter type and complexity.

23. How do minimal APIs differ from controller-based APIs?

Minimal APIs let you define endpoints directly against WebApplication without a controller class, using app.MapGet, app.MapPost, and so on. They cut boilerplate for small, focused APIs and microservices. Controllers still make sense for larger APIs where you want filters, [ApiController] conventions, and a clearer separation between routing and business logic across many endpoints.

csharp
var app = builder.Build();
app.MapGet("/api/products/{id:int}", async (int id, IProductService service) =>
{
var product = await service.GetByIdAsync(id);
return product is not null ? Results.Ok(product) : Results.NotFound();
});
app.MapPost("/api/products", async (ProductDto dto, IProductService service) =>
{
var created = await service.CreateAsync(dto);
return Results.Created($"/api/products/{created.Id}", created);
});
app.Run();

This is functionally equivalent to a small controller, just without the class ceremony. Dependency injection still works the same way — IProductService is resolved from the container per request.

24. What does `[ApiController]` actually do?

It enables several conventions automatically: automatic 400 responses on invalid model state, binding source inference, attribute routing requirement, and problem-details-based error responses. Removing it means you have to handle model validation manually.

25. How would you implement request validation beyond data annotations?

Data annotations ([Required], [StringLength]) cover simple cases well, but for anything conditional or cross-field, most teams reach for FluentValidation or write manual checks inside the action or a dedicated validator service, then return a ValidationProblemDetails response.

26. What's the role of DTOs (Data Transfer Objects) in a Web API?

DTOs decouple your API's public contract from your internal domain or EF Core entity models. Returning entities directly is a common beginner mistake — it leaks internal fields, creates over-fetching problems, and couples your database schema to your API contract in a way that makes both harder to change independently.

27. What is an action filter, and when would you use one?

An action filter runs code before and after an action executes — useful for cross-cutting concerns like logging, response shaping, or short-circuiting a request based on some condition. Result filters specifically wrap the formatting of the response. Filters are a cleaner alternative to duplicating the same logic across many actions.

28. How does dependency injection work with controllers in ASP.NET Core?

Services are registered in the DI container (builder.Services.AddScoped<...>(), etc.) and injected via constructor parameters. ASP.NET Core's built-in container handles the object graph resolution per request scope, which is why most services should be registered as scoped rather than singleton unless they're genuinely stateless or thread-safe.

Versioning, Content Negotiation, and Error Handling

29. What are the common API versioning strategies?

URL segment versioning (/api/v1/orders), query string versioning (/api/orders?api-version=1.0), and header-based versioning (a custom X-Api-Version header or media type versioning). URL versioning is the most visible and easiest for clients to discover; header versioning keeps URLs clean but is less discoverable without documentation.

30. How would you implement versioning in ASP.NET Core?

Asp.Versioning is the actively maintained community successor to the original Microsoft.AspNetCore.Mvc.Versioning package (part of the dotnet-api-versioning project) rather than an in-the-box or officially Microsoft-shipped library, and it adds ApiVersion attributes and conventions for both controllers and minimal APIs. It handles routing multiple versions of the same resource and can be paired with Swashbuckle to generate separate Swagger docs per version.

31. What is ProblemDetails (RFC 7807), and why does it matter for error responses?

ProblemDetails is a standardized JSON structure for HTTP error responses — fields like type, title, status, detail, and instance. ASP.NET Core's [ApiController] convention and its exception-handling middleware use it by default for error responses, which gives API consumers a consistent, machine-readable error shape instead of every team inventing its own error envelope.

32. How do you implement global exception handling in ASP.NET Core?

Typically through UseExceptionHandler middleware configured early in the pipeline, or in newer versions, a custom IExceptionHandler implementation registered via AddExceptionHandler. Either approach catches unhandled exceptions, logs them, and returns a consistent ProblemDetails response instead of leaking a stack trace to the client.

33. What is Swagger/OpenAPI, and what does Swashbuckle do?

OpenAPI is a specification for describing REST APIs in a machine-readable format. Swagger is the tooling ecosystem built around that spec. Swashbuckle is the most common .NET library that generates an OpenAPI document from your controllers and minimal API endpoints and serves an interactive UI for exploring them.

34. How does content negotiation fail gracefully when a client requests an unsupported format?

If a client sends an Accept header for a media type the server has no formatter for, ASP.NET Core by default ignores the unsatisfiable Accept header and serializes the response using the default output formatter (typically JSON) rather than failing the request. It only returns 406 Not Acceptable if you explicitly set options.ReturnHttpNotAcceptable = true.

Authentication, Authorization, and Security

35. How does JWT authentication work at a high level?

The client authenticates once (username/password, or an external identity provider) and receives a signed JSON Web Token. On subsequent requests, the client sends that token in the Authorization: Bearer <token> header. The API validates the signature and claims on every request without needing a server-side session store — which is exactly what statelessness in REST calls for.

36. How would you configure JWT bearer authentication in ASP.NET Core?

csharp
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = builder.Configuration["Jwt:Issuer"],
ValidAudience = builder.Configuration["Jwt:Audience"],
IssuerSigningKey = new SymmetricSecurityKey(
Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"]!))
};
});
builder.Services.AddAuthorization();

app.UseAuthentication() must come before app.UseAuthorization() in the middleware pipeline — a common source of "why is my [Authorize] attribute not working" bugs.

37. What's the difference between authentication and authorization?

Authentication answers "who are you" — verifying identity. Authorization answers "what are you allowed to do" — checking permissions or roles once identity is established. [Authorize] alone checks authentication; [Authorize(Roles = "Admin")] adds an authorization check.

38. What are the main OAuth2 grant types, and where does JWT fit in?

Common flows include Authorization Code (with PKCE for public clients), Client Credentials (service-to-service), and Refresh Token (renewing access without re-prompting the user). JWT isn't an OAuth2 flow itself — it's commonly the token format OAuth2 servers issue as the access token.

39. What's a common CORS misconfiguration mistake?

Setting AllowAnyOrigin() together with AllowCredentials() — the browser explicitly disallows that combination, and ASP.NET Core will throw at runtime if you try to configure it that way. If your API needs cookies or credentials from the browser, you have to name specific allowed origins.

40. How would you handle API key rotation without downtime?

Support two valid keys simultaneously during a transition window — validate incoming requests against either the old or new key, notify consumers of the cutover date, then revoke the old key after they've migrated. Hardcoding a single active key makes rotation an all-or-nothing outage risk.

Performance, Caching, and Rate Limiting

41. What's the difference between output caching and response caching in ASP.NET Core?

Response caching relies on standard HTTP caching headers (Cache-Control) and can be handled by both the server and intermediate proxies/browsers. Output caching (available as built-in middleware in recent ASP.NET Core versions) caches the generated response on the server itself, which can reduce load for expensive endpoints even when clients don't respect cache headers.

42. What is an ETag and how does it help with performance?

An ETag is a hash or version identifier representing a resource's current state. Clients send it back via If-None-Match on subsequent requests; if unchanged, the server returns 304 Not Modified with no body, saving bandwidth and avoiding redundant processing.

43. How would you implement rate limiting in ASP.NET Core?

Recent versions ship a built-in rate limiting middleware (Microsoft.AspNetCore.RateLimiting) supporting strategies like fixed window, sliding window, token bucket, and concurrency limits, configured via AddRateLimiter and applied with .RequireRateLimiting() on endpoints or globally.

csharp
builder.Services.AddRateLimiter(options =>
{
options.AddFixedWindowLimiter("fixed", opt =>
{
opt.PermitLimit = 100;
opt.Window = TimeSpan.FromMinutes(1);
opt.QueueLimit = 10;
opt.QueueProcessingOrder = QueueProcessingOrder.OldestFirst;
});
});
app.UseRateLimiter();
app.MapGet("/api/reports", GetReportsHandler).RequireRateLimiting("fixed");

This caps a client to 100 requests per minute against that endpoint, queuing up to 10 extra requests before rejecting with 429 Too Many Requests.

44. Why would you enable response compression, and what's the tradeoff?

Compression (via AddResponseCompression) reduces payload size over the wire, which helps a lot for JSON-heavy APIs on slower networks. The tradeoff is CPU cost on the server for compressing each response, so it's usually worth it for larger payloads but negligible or even counterproductive for tiny ones.

45. What causes the classic "async all the way" pitfall in Web API controllers?

Mixing blocking calls (.Result, .Wait()) into an otherwise async pipeline can cause thread pool starvation under load, sometimes deadlocking entirely depending on the synchronization context. The fix is straightforward in principle — use await consistently from the controller action down through every layer — but it's easy to accidentally break the chain by calling a synchronous EF Core method or a blocking HTTP client call somewhere in the middle.

Testing REST APIs in ASP.NET Core

46. How do you write integration tests for a Web API without running a separate server?

WebApplicationFactory<TEntryPoint> from the Microsoft.AspNetCore.Mvc.Testing package spins up an in-memory test server backed by your actual Program.cs configuration, letting you send real HttpClient requests against your app in a test project without deploying anything.

47. How would you mock an outbound `HttpClient` call in a unit test?

Rather than mocking HttpClient directly (its public surface isn't easily mockable), the common approach is to mock the HttpMessageHandler it's built on, or better, inject IHttpClientFactory and abstract the outbound call behind your own interface that you can substitute in tests.

48. What's the difference between unit tests and integration tests for an API?

Unit tests isolate a single class or method, typically mocking its dependencies. Integration tests exercise multiple layers together — controller, DI container, middleware pipeline — closer to how the API behaves in production, at the cost of being slower and a bit more brittle to unrelated changes.

Scenario and Design Questions

49. How would you design an endpoint that has to update multiple related resources but one part fails partway through?

Talk through the tradeoffs rather than reciting a single answer: a database transaction keeps things consistent if everything lives in one data store, but for cross-service operations you're usually looking at a saga pattern or outbox pattern, accepting eventual consistency and building in compensating actions for partial failures.

50. When would you choose gRPC or GraphQL over REST for a .NET backend?

gRPC fits high-throughput, low-latency service-to-service communication where you control both ends and want strongly typed contracts via Protocol Buffers — it's a poor fit for public-facing browser clients without a proxy layer. GraphQL fits front ends that need flexible, client-driven queries across many related resources, at the cost of more complexity around caching and rate limiting compared to REST's predictable resource-based URLs. REST remains the safest default for public APIs because of its simplicity, cacheability, and universal tooling support.

Conclusion

REST interview questions for ASP.NET Core roles tend to cluster around three things: whether you understand REST's actual constraints (not just "it uses HTTP"), whether you can wire up the framework-specific pieces like routing, versioning, and JWT auth correctly, and whether you've thought about the operational side — idempotency, rate limiting, error consistency — that separates a toy CRUD API from something running in production. Knowing the difference between 401 and 403, or between PUT and PATCH, gets you through the easy questions; being able to talk through idempotency keys on a payment endpoint or async pitfalls under load is what gets you through the harder ones. Practice explaining these answers out loud, not just recognizing them on a page — interviewers notice the difference. As a next step, try building a small ASP.NET Core Web API that touches versioning, JWT auth, and rate limiting together, since combining those concepts in one project surfaces the integration issues that a Q&A list alone won't show you.

Codingvila provides articles and blogs on web and software development for beginners as well as free Academic projects for final year students in Asp.Net, MVC, C#, Vb.Net, SQL Server, Angular Js, Android, PHP, Java, Python, Desktop Software Application and etc.

If you have any questions, contact us on info.codingvila@gmail.com