This guide shows how to build a production-ready AI API using ASP.NET Core with: Clean Architecture, streaming responses, database storage, and secure configuration.
🏗️ Architecture Overview
API Layer → Application Layer → Infrastructure Layer → Database
- API: Controllers
- Application: Business logic
- Infrastructure: OpenAI + DB
- Database: Chat history
1. Secure Configuration (Environment Variable)
builder.Configuration.AddEnvironmentVariables();
var apiKey = builder.Configuration["OPENAI_API_KEY"];
⚠️ Never store API keys in appsettings.json in production.
2. Database Model (Chat History)
public class ChatMessage
{
public int Id { get; set; }
public string UserMessage { get; set; }
public string BotResponse { get; set; }
public DateTime CreatedAt { get; set; }
}
3. DbContext (EF Core)
public class AppDbContext : DbContext
{
public DbSet<ChatMessage> ChatMessages { get; set; }
public AppDbContext(DbContextOptions<AppDbContext> options)
: base(options) { }
}
4. OpenAI Service (Production Ready)
public class OpenAIService
{
private readonly HttpClient _httpClient;
private readonly IConfiguration _config;
public OpenAIService(HttpClient httpClient, IConfiguration config)
{
_httpClient = httpClient;
_config = config;
}
public async Task<string> GetResponseAsync(string prompt)
{
var request = new
{
model = "gpt-4o-mini",
messages = new[]
{
new { role = "user", content = prompt }
}
};
_httpClient.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", _config["OPENAI_API_KEY"]);
var response = await _httpClient.PostAsJsonAsync(
"https://api.openai.com/v1/chat/completions", request);
if (!response.IsSuccessStatusCode)
throw new Exception("OpenAI API error");
var result = await response.Content.ReadFromJsonAsync<dynamic>();
return result.choices[0].message.content;
}
}
5. Streaming Response (Real-Time)
[HttpPost("stream")]
public async Task Stream([FromBody] string prompt)
{
Response.ContentType = "text/plain";
var response = await _service.GetResponseAsync(prompt);
foreach (var word in response.Split(" "))
{
await Response.WriteAsync(word + " ");
await Response.Body.FlushAsync();
await Task.Delay(50);
}
}
✅ Simulates real-time typing (like ChatGPT)
6. Save Chat History
public async Task SaveChat(string userMsg, string botMsg)
{
var chat = new ChatMessage
{
UserMessage = userMsg,
BotResponse = botMsg,
CreatedAt = DateTime.UtcNow
};
_context.ChatMessages.Add(chat);
await _context.SaveChangesAsync();
}
7. Controller (Final Version)
[ApiController]
[Route("api/chat")]
public class ChatController : ControllerBase
{
private readonly OpenAIService _service;
private readonly AppDbContext _context;
public ChatController(OpenAIService service, AppDbContext context)
{
_service = service;
_context = context;
}
[HttpPost]
public async Task<IActionResult> Ask(string prompt)
{
var response = await _service.GetResponseAsync(prompt);
await _context.ChatMessages.AddAsync(new ChatMessage
{
UserMessage = prompt,
BotResponse = response,
CreatedAt = DateTime.UtcNow
});
await _context.SaveChangesAsync();
return Ok(response);
}
}
8. Logging (Serilog)
builder.Host.UseSerilog((ctx, lc) =>
lc.WriteTo.Console()
);
9. Rate Limiting
builder.Services.AddRateLimiter(options =>
{
options.AddFixedWindowLimiter("api", opt =>
{
opt.PermitLimit = 50;
opt.Window = TimeSpan.FromMinutes(1);
});
});
🔐 Enterprise Best Practices
- Use Redis for caching responses
- Store chat history per user
- Use JWT authentication
- Add retry policy (Polly)
- Use Azure Key Vault
- Implement circuit breaker
💡 Real Product Ideas
- AI Customer Support API
- WhatsApp Auto Reply Bot
- AI Code Review Tool
- Content Generator SaaS
📌 Conclusion
You now have a complete enterprise-grade AI API using ASP.NET Core. This can be extended into a scalable SaaS product.
No comments:
Post a Comment