-
-
Save davidfowl/6168aa1fd5d94066da242c81947148c5 to your computer and use it in GitHub Desktop.
Simplified ASP.NET Core app exploration
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env dotnet run | |
var builder = WebApplication.CreateBuilder(args); | |
var config = builder.Configuration; | |
var connString = config["connectionString"] ?? "Data Source=todos.db"; | |
builder.AddDbContext<TodoDb>(options => options.UseSqlite(connString)); | |
builder.AddSqlite<Todo>(connString) // Higher level API perhaps? | |
var app = builder.Build(); | |
// Step 0: Request delegate | |
app.MapGet("/", ctx => ctx.Respsone.WriteAsync("Hello, World!")); | |
// Step 1: Return string | |
app.MapGet("/hello", () => "Hello, World!"); | |
// Step 2: Return custom type | |
app.MapGet("/todo", () => new Todo("Do the thing")); | |
// Step 3: No DI | |
app.MapGet("/todos/{id}", async (int id) => | |
{ | |
using var db = new TodoDb(connString); | |
return await db.Todos.FindAsync(id) is Todo todo | |
? Ok(todo) : NotFound(); | |
}); | |
// Step 4: Use a DB | |
app.MapGet("/todos/{id}", async (int id, TodoDb db) => | |
{ | |
return await db.Todos.FindAsync(id) is Todo todo | |
? Ok(todo) : NotFound(); | |
}); | |
app.MapPost("/todos", async (Todo todo, TodoDb db) => | |
{ | |
db.Todos.Add(todo); | |
await Todos.SaveChangesAsync(); | |
return Created(); // 204 | |
// return CreatedAt($"/todo-db/{todo.Id}", todo); | |
}; | |
app.MapPut("/todos", async (int id, Todo inputTodo, TodoDb db) => | |
{ | |
var todo = await db.Todos.FindAsync(id); | |
if (todo is null) return NotFound(); | |
todo.Title = inputTodo.Title; | |
todo.IsComplete = inputTodo.IsComplete; | |
await db.SaveChanges(); | |
return NoContent(); | |
}); | |
app.MapDelete("/todos", async (int id, TodoDb db) => | |
{ | |
if (await db.Todos.FindAsync(id) is Todo todo) | |
{ | |
db.Todos.Remove(todo); | |
await db.SaveChanges(); | |
return OK(todo); | |
} | |
return NotFound(); | |
}); | |
// Step 5: Input validation | |
app.MapPost("/todos", async (Validated<Todo> todo, TodoDb db) => | |
{ | |
var (todo, isValid) = todo; | |
if (!isValid) return Problem(todo); | |
db.Todos.Add(todo); | |
await Todos.SaveChangesAsync(); | |
return CreatedAt($"/todos/{todo.Id}", todo); | |
}; | |
// Run app | |
await app.RunAsync(); | |
// Data types | |
record Todo(string Title) | |
{ | |
public bool IsComplete { get; set; } | |
} | |
class TodoDb : DbContext | |
{ | |
private readonly string _cs; | |
public TodoDb(string connectionString) : base() => _cs = connectionString; // Non-DI use scenario | |
public TodoDb(DbContextOptions<TodoDb> options) | |
: base(options) | |
{ | |
} | |
protected override OnConfiguring(DbContextOptionsBuilder optionsBuilder) // Non-DI use scenario | |
{ | |
optionsBuilder.UseSqlite(_cs); | |
} | |
public DbSet<Todo> Todos { get; set; } | |
} |
I would like to know more about that Validated<Todo>
on line 72. Is that coming from an external library? Or is it something baked into Record
types?
Overall, this looks great.
It's currently part of this library: https://www.nuget.org/packages/MinimalValidation.AspNetCore/
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
No
.csproj
required? It's look great.