Created
November 12, 2023 22:45
-
-
Save tebeco/cc4f517937e959ecb01826ea5c628320 to your computer and use it in GitHub Desktop.
Hteuteupeu
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
{ | |
"Logging": { | |
"LogLevel": { | |
"Default": "Information", | |
"Microsoft.AspNetCore": "Warning" | |
} | |
}, | |
"AllowedHosts": "*", | |
"Foo": { | |
"Url": "https://jsonplaceholder.typicode.com" | |
} | |
} |
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
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