Skip to content

Commit

Permalink
refactor: use typed client and refactor the httpclient usage
Browse files Browse the repository at this point in the history
  • Loading branch information
aa89227 committed Mar 20, 2024
1 parent 67bd4a8 commit 2ce41eb
Show file tree
Hide file tree
Showing 9 changed files with 73 additions and 40 deletions.
38 changes: 38 additions & 0 deletions Monopoly.Web/HttpClients/MonopolyApiClient.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using System.Net.Http.Headers;
using System.Net.Http.Json;

namespace Client.HttpClients;

public class MonopolyApiClient(HttpClient httpClient)
{
public async Task<IEnumerable<PlayerModel>> GetPlayers()
{
var response = await httpClient.GetAsync("/users");
response.EnsureSuccessStatusCode();
return await response.Content.ReadFromJsonAsync<IEnumerable<PlayerModel>>() ?? [];
}

public async Task<IEnumerable<string>> GetRooms()
{
var response = await httpClient.GetAsync("/rooms");
response.EnsureSuccessStatusCode();
return await response.Content.ReadFromJsonAsync<IEnumerable<string>>() ?? [];
}

public async Task CreateGame(string hostToken, IEnumerable<PlayerModel> players)
{
var payload = new
{
Players = players.ToArray()
};
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", hostToken);
var response = await httpClient.PostAsJsonAsync("/games", payload);
response.EnsureSuccessStatusCode();
}
}

public class PlayerModel
{
public required string Id { get; set; }
public required string Token { get; set; }
}
1 change: 1 addition & 0 deletions Monopoly.Web/Monopoly.Web.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="8.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="8.0.0" PrivateAssets="all" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Http" Version="8.0.0" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
namespace Client.Options;

public class BackendApiOptions
public class MonopolyApiOptions
{
public string BaseUrl { get; set; } = default!;
public BackendApiOptions()
public MonopolyApiOptions()
{

}
Expand Down
4 changes: 2 additions & 2 deletions Monopoly.Web/Pages/DevPage.razor
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<div class="background">
<div class="players">
@foreach (var player in players)
@foreach (var player in _players)
{
<div class="player">
<div class="player-id">@player.Id</div>
Expand All @@ -12,7 +12,7 @@
</div>
<div class="create-room" @onclick="CreateGame">Create Room</div>
<div class="rooms">
@foreach (var room in rooms)
@foreach (var room in _rooms)
{
<div class="room">
<div class="room-id">@room.Id</div>
Expand Down
45 changes: 17 additions & 28 deletions Monopoly.Web/Pages/DevPage.razor.cs
Original file line number Diff line number Diff line change
@@ -1,62 +1,51 @@
using Client.Options;
using Microsoft.AspNetCore.Components;
using Microsoft.Extensions.Options;
using System.Net.Http.Headers;
using System.Net.Http.Json;
using Client.HttpClients;

namespace Client.Pages;

public partial class DevPage
{
private IEnumerable<Player>? players = [];
private IEnumerable<Room>? rooms = [];
[Inject] private IOptions<BackendApiOptions> BackendApiOptions { get; set; } = default!;
private IEnumerable<Player> _players = [];
private IEnumerable<Room>? _rooms = [];
[Inject] private NavigationManager NavigationManager { get; set; } = default!;
private Uri BackendApiBaseUri => new(BackendApiOptions.Value.BaseUrl);
[Inject] private MonopolyApiClient MonopolyApiClient { get; set; } = default!;

protected override async Task OnInitializedAsync()
{
var users = await new HttpClient().GetFromJsonAsync<Player[]>(new Uri(BackendApiBaseUri, "/users"));
players = users?.Select(p => new Player(p.Id, p.Token));
var users = await MonopolyApiClient.GetPlayers();
_players = users.Select(p => new Player(p.Id, p.Token));
}

private async void CreateGame()
{
CreateGameBodyPayload bodyPayload = new([.. players]);
var url = new Uri(BackendApiBaseUri, "/games");
var httpClient = new HttpClient();
var host = players?.FirstOrDefault();
CreateGameBodyPayload bodyPayload = new([.. _players]);
var host = _players.FirstOrDefault();
if (host is null)
{
//Snackbar.Add("請先加入使用者", Severity.Error);
return;
}
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", host.Token);
var response = await httpClient.PostAsJsonAsync(url, bodyPayload);
if (response.IsSuccessStatusCode)
{
var content = await response.Content.ReadAsStringAsync();
//Snackbar.Add($"遊戲建立成功! Url: {content}", Severity.Normal);
await RefleshRoomListAsync();
}
else
{
//Snackbar.Add($"遊戲建立失敗! {response.StatusCode}", Severity.Error);
}

await MonopolyApiClient.CreateGame(host.Token, _players.Select(x => new PlayerModel { Id = x.Id, Token = x.Token }));
await RefleshRoomListAsync();
}

private async Task RefleshRoomListAsync()
{
var roomIds = await new HttpClient().GetFromJsonAsync<List<string>>(new Uri(BackendApiBaseUri, "/rooms"));
rooms = roomIds?.Select(id => new Room(id, [.. players]));
var roomIds = await MonopolyApiClient.GetRooms();
_rooms = roomIds.Select(id => new Room(id, [.. _players]));
StateHasChanged();
}

private void EnterRoom(Room room, Player player)
{
NavigationManager.NavigateTo($"games/{room.Id}?token={player.Token}");
}

private record CreateGameBodyPayload(Player[] Players);

private record Player(string Id, string Token);

record Room(string Id, IEnumerable<Player> Players);
}
}
2 changes: 1 addition & 1 deletion Monopoly.Web/Pages/Index.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public partial class Index

[Parameter, SupplyParameterFromQuery(Name = "token")]
public string AccessToken { get; set; } = default!;
[Inject] private IOptions<BackendApiOptions> BackendApiOptions { get; set; } = default!;
[Inject] private IOptions<MonopolyApiOptions> BackendApiOptions { get; set; } = default!;
private string UserId { get; set; } = string.Empty;
private List<string> Messages { get; } = [];
public bool IsGameStarted { get; set; } = false;
Expand Down
15 changes: 10 additions & 5 deletions Monopoly.Web/Program.cs
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
using Client;
using Client.HttpClients;
using Client.Options;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using Microsoft.Extensions.Options;

var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");
builder.RootComponents.Add<HeadOutlet>("head::after");

builder.Services.AddOptions<BackendApiOptions>()
.Configure(options =>
{
builder.Configuration.GetSection(nameof(BackendApiOptions)).Bind(options);
});
builder.Services.AddOptions<MonopolyApiOptions>()
.Configure(options => { builder.Configuration.GetSection(nameof(MonopolyApiOptions)).Bind(options); });
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });

// Register the MonopolyApiClient
builder.Services.AddHttpClient<MonopolyApiClient>(client =>
{
var backendApiOptions = builder.Services.BuildServiceProvider().GetRequiredService<IOptions<MonopolyApiOptions>>().Value;
client.BaseAddress = new Uri(backendApiOptions.BaseUrl);
});
await builder.Build().RunAsync();
2 changes: 1 addition & 1 deletion Monopoly.Web/wwwroot/appsettings.Development.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"BackendApiOptions": {
"MonopolyApiOptions": {
"BaseUrl": "https://localhost:3826/"
}
}
2 changes: 1 addition & 1 deletion Monopoly.Web/wwwroot/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<base href="/" />
<link href="css/app.css?version=0.32" rel="stylesheet" />

<link href="Client.styles.css" rel="stylesheet" />
<link href="Monopoly.Web.styles.css" rel="stylesheet" />
<link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap" rel="stylesheet" />
</head>

Expand Down

0 comments on commit 2ce41eb

Please sign in to comment.