Building a RESTful API with ASP.NET Core: Step-by-Step Guide


📋 Table of Contents
Introduction
Prerequisites
Creating the Project
Understanding the Project Structure
Configuration Files
appsettings.json
launchSettings.json
Creating DTOs
Creating Routes and Controllers
Implementing JWT Authentication
What is JWT?
JWT Configuration
Token Generation
AuthController
Protecting Endpoints
Example JWT Token
External Decoding
API Versioning
Documenting with Swagger
What is Swagger?
Swagger Configuration
Testing with Postman
Conclusion
🧾 1. Introduction
In this article, you’ll learn how to build a modern RESTful API using ASP.NET Core, covering essential concepts like routes, controllers, DTOs, API versioning, Swagger for documentation, and JWT authentication.
Perfect for developers starting with .NET APIs or looking to reinforce best practices in architecture and security.
🛠️ 2. Prerequisites
Visual Studio or VS Code
Basic understanding of C# and HTTP
Postman or another API testing tool
🛠️3. Creating the Project
Create a new ASP.NET Core Web API project:
dotnet new webapi -n MyApiProject
cd MyApiProject
This will generate a basic structure with a sample controller.
🧩 4. Understanding the Project Structure
Key folders and files:
Controllers/
: where your API controllers liveProgram.cs
andStartup.cs
(or justProgram.cs
in .NET 6+)appsettings.json
: settings like JWT keyslaunchSettings.json
: local run profile
⚙️ 5. Configuration Files
appsettings.json
{
"Jwt": {
"Key": "my-super-secret-key",
"Issuer": "MyApiIssuer",
"Audience": "MyApiAudience"
}
}
Explanation:
Stores JWT settings like secret key, issuer, and audience used for token validation.
launchSettings.json
"profiles": {
"MyApiProject": {
"applicationUrl": "https://localhost:5001;http://localhost:5000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
Explanation:
Defines how the app runs locally, including URLs and environment mode.
📦 6. Creating DTOs
LoginDto
public class LoginDto
{
public string Username { get; set; }
public string Password { get; set; }
}
Explanation:
Receives login credentials from the client during authentication.
ProductDto
public class ProductDto
{
public int Id { get; set; }
public string Name { get; set; }
}
Explanation:
Represents product data returned by the API.
🧭 7. Creating Routes and Controllers
ProductsController
[ApiController]
[Route("api/v1/[controller]")]
public class ProductsController : ControllerBase
{
[HttpGet]
[Authorize]
public IActionResult GetAll()
{
var products = new List<ProductDto>
{
new ProductDto { Id = 1, Name = "Product A" },
new ProductDto { Id = 2, Name = "Product B" }
};
return Ok(products);
}
}
Explanation:
Defines a GET endpoint at /api/v1/products
that returns a list of products. The [Authorize]
attribute ensures only authenticated users can access it.
🔐 8. Implementing JWT Authentication
What is JWT?
JWT (JSON Web Token) is a secure way to transmit user identity and claims between client and server.
JWT Configuration (Program.cs)
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = "MyApiIssuer",
ValidAudience = "MyApiAudience",
IssuerSigningKey = new SymmetricSecurityKey(
Encoding.UTF8.GetBytes("my-super-secret-key"))
};
});
builder.Services.AddAuthorization();
app.UseAuthentication();
app.UseAuthorization();
Explanation:
Configures JWT authentication and authorization. Tokens are validated based on issuer, audience, expiration, and signature.
Token Generation Method
private string GenerateJwtToken()
{
var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("my-super-secret-key"));
var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);
var claims = new[]
{
new Claim(ClaimTypes.Name, "admin"),
new Claim(ClaimTypes.Role, "Administrator")
};
var token = new JwtSecurityToken(
issuer: "MyApiIssuer",
audience: "MyApiAudience",
claims: claims,
expires: DateTime.Now.AddHours(1),
signingCredentials: credentials
);
return new JwtSecurityTokenHandler().WriteToken(token);
}
Explanation:
Generates a JWT token with user claims and expiration. Uses HMAC SHA256 to sign the token securely.
AuthController
[ApiController]
[Route("api/v1/[controller]")]
public class AuthController : ControllerBase
{
[HttpPost("login")]
public IActionResult Login([FromBody] LoginDto login)
{
if (login.Username == "admin" && login.Password == "123")
{
var token = GenerateJwtToken();
return Ok(new { token });
}
return Unauthorized();
}
private string GenerateJwtToken()
{
// Same method as above
}
}
Explanation:
Handles login requests. If credentials are valid, returns a JWT token. Otherwise, returns 401 Unauthorized.
Example JWT Token
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Explanation:
This is a sample JWT token. It contains encoded user info and is used to access protected endpoints.
External Decoding
Use jwt.io to decode and inspect your token.
Explanation:
You can view the token’s header, payload (claims), and signature to verify its contents.
📚 10. Documenting with Swagger
Swagger Configuration
builder.Services.AddSwaggerGen();
app.UseSwagger();
app.UseSwaggerUI();
Explanation:
Enables Swagger UI at /swagger
, allowing you to explore and test your API interactively.
🧪 11. Testing with Postman
- Send POST to
/api/v1/auth/login
with:
{
"username": "admin",
"password": "123"
}
Copy the token from the response.
Send GET to
/api/v1/products
with header:
Authorization: Bearer <your_token_here>
Explanation:
This simulates a login and authenticated request using JWT. Postman helps test endpoints easily.
🏁 12. Conclusion
You now have a fully functional ASP.NET Core API with:
Clean architecture
JWT authentication
API versioning
Swagger documentation
This setup is perfect for scalable backend systems and can be extended with databases, role-based access, and more.
#AspNetCore #DotNet #CSharp #DotNetDev #DotNetCommunity #WebAPI #RESTAPI #BackendDevelopment #APIDevelopment #Microservices #JWT #Authentication #SecureAPI #TokenBasedAuth #Swagger #OpenAPI #CleanCode #SoftwareArchitecture #DevTips #CodeNewbie #LearnToCode #100DaysOfCode #TechTutorial
Subscribe to my newsletter
Read articles from Johnny Hideki Kinoshita de Faria directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Johnny Hideki Kinoshita de Faria
Johnny Hideki Kinoshita de Faria
Technology professional with over 15 years of experience delivering innovative, scalable, and secure solutions — especially within the financial sector. I bring deep expertise in Oracle PL/SQL (9+ years), designing robust data architectures that ensure performance and reliability. On the back-end side, I’ve spent 6 years building enterprise-grade applications using .NET, applying best practices like TDD and clean code to deliver high-quality solutions. In addition to my backend strengths, I have 6 years of experience with PHP and JavaScript, allowing me to develop full-stack web applications that combine strong performance with intuitive user interfaces. I've led and contributed to projects involving digital account management, integration of VISA credit and debit transactions, modernization of payment systems, financial analysis tools, and fraud prevention strategies. Academically, I hold a postgraduate certificate in .NET Architecture and an MBA in IT Project Management, blending technical skill with business acumen. Over the past 6 years, I’ve also taken on leadership roles — managing teams, mentoring developers, and driving strategic initiatives. I'm fluent in agile methodologies and make consistent use of tools like Azure Boards to coordinate tasks and align team performance with delivery goals.