C#/Blazor
[Blazor] Github API 이용해 Repository 조회하기
kjun.kr
2023. 2. 7. 21:49
728x90
728x170
사용할 Model 추가
SearchResult.cs
using System.Text.Json.Serialization;
namespace Blazor.GitTest.Models
{
public class SearchResult<T>
{
[JsonPropertyName("total_count")]
public int TotalCount { get; set; }
[JsonPropertyName("incomplete_results")]
public bool IncompleteResults { get; set; }
[JsonPropertyName("items")]
public List<T> Items { get; set; }
}
}
Repository.cs
using System.Text.Json.Serialization;
namespace Blazor.GitTest.Models
{
public class Repository
{
[JsonPropertyName("id")]
public int Id { get; set; }
[JsonPropertyName("name")]
public string Name { get; set; }
[JsonPropertyName("full_name")]
public string FullName { get; set; }
[JsonPropertyName("owner")]
public Owner Owner { get; set; }
[JsonPropertyName("private")]
public bool Private { get; set; }
[JsonPropertyName("html_url")]
public string HtmlUrl { get; set; }
[JsonPropertyName("description")]
public string Description { get; set; }
[JsonPropertyName("fork")]
public bool Fork { get; set; }
[JsonPropertyName("url")]
public string Url { get; set; }
[JsonPropertyName("forks_url")]
public string ForksUrl { get; set; }
[JsonPropertyName("keys_url")]
public string KeysUrl { get; set; }
[JsonPropertyName("collaborators_url")]
public string CollaboratorsUrl { get; set; }
[JsonPropertyName("teams_url")]
public string TeamsUrl { get; set; }
[JsonPropertyName("hooks_url")]
public string HooksUrl { get; set; }
[JsonPropertyName("issue_events_url")]
public string IssueEventsUrl { get; set; }
[JsonPropertyName("events_url")]
public string EventsUrl { get; set; }
[JsonPropertyName("assignees_url")]
public string AssigneesUrl { get; set; }
[JsonPropertyName("branches_url")]
public string BranchesUrl { get; set; }
[JsonPropertyName("tags_url")]
public string TagsUrl { get; set; }
[JsonPropertyName("blobs_url")]
public string BlobsUrl { get; set; }
[JsonPropertyName("git_tags_url")]
public string GitTagsUrl { get; set; }
[JsonPropertyName("git_refs_url")]
public string GitRefsUrl { get; set; }
[JsonPropertyName("trees_url")]
public string TreesUrl { get; set; }
[JsonPropertyName("statuses_url")]
public string StatusesUrl { get; set; }
[JsonPropertyName("languages_url")]
public string LanguagesUrl { get; set; }
[JsonPropertyName("stargazers_url")]
public string StargazersUrl { get; set; }
[JsonPropertyName("contributors_url")]
public string ContributorsUrl { get; set; }
[JsonPropertyName("subscribers_url")]
public string SubscribersUrl { get; set; }
[JsonPropertyName("subscription_url")]
public string SubscriptionUrl { get; set; }
[JsonPropertyName("commits_url")]
public string CommitsUrl { get; set; }
[JsonPropertyName("git_commits_url")]
public string GitCommitsUrl { get; set; }
[JsonPropertyName("comments_url")]
public string CommentsUrl { get; set; }
[JsonPropertyName("issue_comment_url")]
public string IssueCommentUrl { get; set; }
[JsonPropertyName("contents_url")]
public string ContentsUrl { get; set; }
[JsonPropertyName("compare_url")]
public string CompareUrl { get; set; }
[JsonPropertyName("merges_url")]
public string MergesUrl { get; set; }
[JsonPropertyName("archive_url")]
public string ArchiveUrl { get; set; }
[JsonPropertyName("downloads_url")]
public string DownloadsUrl { get; set; }
[JsonPropertyName("issues_url")]
public string IssuesUrl { get; set; }
[JsonPropertyName("pulls_url")]
public string PullsUrl { get; set; }
[JsonPropertyName("milestones_url")]
public string MilestonesUrl { get; set; }
[JsonPropertyName("notifications_url")]
public string NotificationsUrl { get; set; }
[JsonPropertyName("labels_url")]
public string LabelsUrl { get; set; }
[JsonPropertyName("releases_url")]
public string ReleasesUrl { get; set; }
[JsonPropertyName("created_at")]
public string CreatedAt { get; set; }
[JsonPropertyName("updated_at")]
public string UpdatedAt { get; set; }
[JsonPropertyName("pushed_at")]
public string PushedAt { get; set; }
[JsonPropertyName("git_url")]
public string GitUrl { get; set; }
[JsonPropertyName("ssh_url")]
public string SshUrl { get; set; }
[JsonPropertyName("clone_url")]
public string CloneUrl { get; set; }
[JsonPropertyName("svn_url")]
public string SvnUrl { get; set; }
[JsonPropertyName("homepage")]
public object Homepage { get; set; }
[JsonPropertyName("size")]
public int Size { get; set; }
[JsonPropertyName("stargazers_count")]
public int StargazersCount { get; set; }
[JsonPropertyName("watchers_count")]
public int WatchersCount { get; set; }
[JsonPropertyName("language")]
public object Language { get; set; }
[JsonPropertyName("has_issues")]
public bool HasIssues { get; set; }
[JsonPropertyName("has_downloads")]
public bool HasDownloads { get; set; }
[JsonPropertyName("has_wiki")]
public bool HasWiki { get; set; }
[JsonPropertyName("has_pages")]
public bool HasPages { get; set; }
[JsonPropertyName("forks_count")]
public int ForksCount { get; set; }
[JsonPropertyName("mirror_url")]
public object MirrorUrl { get; set; }
[JsonPropertyName("open_issues_count")]
public int OpenIssuesCount { get; set; }
[JsonPropertyName("forks")]
public int Forks { get; set; }
[JsonPropertyName("open_issues")]
public int OpenIssues { get; set; }
[JsonPropertyName("watchers")]
public int Watchers { get; set; }
[JsonPropertyName("default_branch")]
public string DefaultBranch { get; set; }
[JsonPropertyName("organization")]
public Organization Organization { get; set; }
[JsonPropertyName("network_count")]
public int NetworkCount { get; set; }
[JsonPropertyName("subscribers_count")]
public int SubscribersCount { get; set; }
}
}
GitHubClient.cs 추가
using System.Net.Http.Headers;
using System.Net.Http.Json;
using Blazor.GitTest.Models;
namespace Blazor.GitTest
{
public class GitHubClient
{
public HttpClient HttpClient { get; }
public GitHubClient(HttpClient httpClient)
{
httpClient.BaseAddress = new Uri("https://api.github.com/");
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/vnd.github.v3+json"));
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/vnd.github.mercy-preview+json"));
httpClient.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("GitHubClient", "1.0.0"));
HttpClient = httpClient;
}
public async Task<SearchResult<Repository>> SearchRepositories(string text, int? page = null, int? pageSize = null)
{
var encoded = Uri.EscapeDataString(text);
var url = $"search/repositories?q={encoded}";
if (page > 0)
url += $"&page={page}";
if (pageSize > 0)
url += $"&per_page={pageSize}";
var result = await HttpClient.GetFromJsonAsync<SearchResult<Repository>>(url);
return result;
}
}
}
Program.cs 에서 GitHubClient 주입
builder.Services.AddScoped<GitHubClient>();
FetchData.razor 화면 처리
@page "/fetchdata"
@using Blazor.GitTest.Models;
@inject HttpClient Http
@inject GitHubClient GitHubClient
<PageTitle>Weather forecast</PageTitle>
<h1>Search Github 'keisoft'</h1>
@if (repositoryList == null)
{
<p><em>Loading...</em></p>
}
else
{
<table class="table">
<thead>
<tr>
<th>FullName</th>
<th>Description</th>
<th>Statistics</th>
</tr>
</thead>
<tbody>
@foreach (var repo in repositoryList)
{
<tr>
<td><div class="github-title">@repo.FullName</div></td>
<td><div class="github-description">@repo.Description</div></td>
<td>
<div class="github-statistics">
<div class="github-forks"> @repo.ForksCount Forks</div>
<div class="github-stargazers"> @repo.StargazersCount Stars</div>
<div class="github-watchers"> @repo.SubscribersCount Watchers</div>
</div>
</td>
</tr>
}
</tbody>
</table>
}
@code {
private List<Repository>? repositoryList;
protected override async Task OnInitializedAsync()
{
var result = await GitHubClient.SearchRepositories("keisoft", 1, 20);
repositoryList = result.Items;
}
}
wwwroot/css/app.css 에 Github Style 추가
/* GitHub */
.github-repository {
padding-top: 4px;
padding-bottom: 3px;
}
.github-avatar {
float: left;
width: 60px;
margin-right: 10px;
}
.github-avatar img {
width: 100%;
height: auto;
border-radius: 2px;
}
.github-meta {
margin-left: 70px;
}
.github-title {
color: black;
font-weight: 700;
word-wrap: break-word;
line-height: 1.1;
margin-bottom: 4px;
}
.github-description {
font-size: 13px;
color: #777;
margin-top: 4px;
}
.github-forks,
.github-stargazers,
.github-watchers {
display: inline-block;
color: #aaa;
font-size: 11px;
}
.github-forks,
.github-stargazers {
margin-right: 1em;
}
결과
* 추후 paging 기능을 처리하기 위해 page 관련 필드 및 인자가 추가되 있는 상태입니다.
[Source]
https://github.com/kei-soft/Blazor.AppTest/tree/master/Blazor.GitTest
728x90
그리드형