Skip to content

Instantly share code, notes, and snippets.

@tebeco
Created November 12, 2023 22:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tebeco/cc4f517937e959ecb01826ea5c628320 to your computer and use it in GitHub Desktop.
Save tebeco/cc4f517937e959ecb01826ea5c628320 to your computer and use it in GitHub Desktop.
Hteuteupeu
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"Foo": {
"Url": "https://jsonplaceholder.typicode.com"
}
}
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Options;
using System.Net.Http.Headers;
using System.Net.Http.Json;
using System.Text.Json.Serialization;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddFoo();
builder.Services.AddHealthChecks();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.MapGet("/foo", async (FooHttpClient fooHttpClient) =>
{
var todo = await fooHttpClient.GetTodo(1);
return Results.Ok(todo);
})
.WithName("GetFoo")
.WithOpenApi();
app.MapPost("/foo", async (FooHttpClient fooHttpClient, [FromBody] CreatePostDto dto) =>
{
await fooHttpClient.CreatePost(new CreateFooPostDto(dto.UserId, dto.Title, dto.Body));
return Results.Ok();
})
.WithName("CreateFoo")
.WithOpenApi();
app.MapHealthChecks("/hc");
app.Run();
public static class FooExtesions
{
public static IServiceCollection AddFoo(this IServiceCollection services)
{
services
.AddOptions<FooOptions>()
.BindConfiguration(FooOptions.SectionName)
.Validate(options => options.Url != null, "should not be null")
.Validate(options => options.Url?.IsAbsoluteUri ?? false, "should be absolute url")
.ValidateOnStart()
;
services.AddTransient<FooTokenFactory>();
services.AddTransient<FooAuthenticationMessageHandler>();
services
.AddHttpClient<FooHttpClient>((sp, httpClient) =>
{
var fooOptions = sp.GetRequiredService<IOptions<FooOptions>>().Value;
httpClient.BaseAddress = fooOptions.Url;
})
.AddHttpMessageHandler((sp) =>
{
var handler = sp.GetRequiredService<FooAuthenticationMessageHandler>();
return handler;
})
;
return services;
}
}
public class FooHttpClient(HttpClient _httpClient)
{
public async Task<IEnumerable<Todo>> GetTodos()
=> await _httpClient.GetFromJsonAsync<IEnumerable<Todo>>($"/todos") ?? [];
public async Task<Todo?> GetTodo(int id)
=> await _httpClient.GetFromJsonAsync<Todo>($"/todos/{id}");
public async Task<IEnumerable<Post>> GetPost()
=> await _httpClient.GetFromJsonAsync<IEnumerable<Post>>($"/posts") ?? [];
public async Task<Post?> GetPost(int id)
=> await _httpClient.GetFromJsonAsync<Post>($"/posts/{id}");
public async Task CreatePost(CreateFooPostDto createPostDto)
{
var result = await _httpClient.PostAsJsonAsync<CreateFooPostDto>($"/posts", createPostDto);
var content = result.Content.ReadFromJsonAsync<WahteverTypeYouWant>();
}
}
public record WahteverTypeYouWant();
public class FooTokenFactory
{
public Guid GetToken() => Guid.NewGuid();
}
public class FooAuthenticationMessageHandler(FooTokenFactory _fooTokenFactory) : DelegatingHandler
{
private Guid GetToken()
{
return _fooTokenFactory.GetToken();
}
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", GetToken().ToString());
return base.SendAsync(request, cancellationToken);
}
}
public record Todo(
[property: JsonPropertyName("id")] int Id,
[property: JsonPropertyName("userId")] int UserId,
[property: JsonPropertyName("title")] string Title,
[property: JsonPropertyName("completed")] bool Completed
);
public record Post(
[property: JsonPropertyName("id")] int Id,
[property: JsonPropertyName("userId")] int UserId,
[property: JsonPropertyName("title")] string Title,
[property: JsonPropertyName("body")] string Body
);
public record CreateFooPostDto(
[property: JsonPropertyName("userId")] int UserId,
[property: JsonPropertyName("title")] string Title,
[property: JsonPropertyName("body")] string Body
);
public record CreatePostDto(
[property: JsonPropertyName("userId")] int UserId,
[property: JsonPropertyName("title")] string Title,
[property: JsonPropertyName("body")] string Body
);
public class FooOptions
{
public const string SectionName = "Foo";
public Uri Url { get; set; } = null!;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment