今からでも間に合う

技術を学ぶのは今からでも遅くない

はてなブログの記事をHttpClientで取得する

Blazor Server/Clientの実装をもっと試したかったので作ってみました。
あとでデータベースも扱ってみたいということもあり、ある程度のデータがあるはてなブログの情報を取得してみます。

構成

  • VS2022
  • .NET6
  • Blazor WebAssemblyプロジェクト
    • HTTPS用の構成
    • ASP.NET Core Hosted

super-string37.com

↑と同じ構成です。githubにソースもあるので、そこをベースに進めていきます。

事前準備

記事情報を取得するためには認証が必要になります。
その際のパスワード扱いとなるAPIキーを取得します。

はてなブログのAPIキー取得

はてなブログの管理ページから
[アカウント設定] - [基本設定] - [APIキー]
に進み、キーを取得します。

サーバー側の実装

サーバー側は、クライアントからの要求を受け付けたら、はてなブログに処理を要求します。
せっかくWebAssemblyの構成で作っているので、パース処理とか重そうな処理はクライアント側でやらせます。
そのため、サーバ側は受け取った文字列をそのまま文字列でクライアント側に返します。

コントローラーの実装
[Route("api/[controller]")]
[ApiController]
public class HatenaEntryController : ControllerBase
{
    private readonly HttpClient _client;
    public HatenaEntryController(IHttpClientFactory factory)
    {
        _client = factory.CreateClient("HatenaEntry");
    }

    [HttpGet]
    public string Get()
    {
        return GetAsync().Result;
    }

    private async Task<string> GetAsync()
    {
        var ret = await _client.GetAsync("entry");
        if (!ret.IsSuccessStatusCode)
        {
            return string.Empty;
        }
        return await ret.Content.ReadAsStringAsync();
    }
}

ここは前回と変わらずです。
最初に書いたように文字列でそのまま返しています。
そして相変わらずエラー処理は皆無です。

BASIC認証

ここが個人的に一番難解でした。
認証はわかるけど、その種類なんか知らんし何をどう設定したらいいかもわからない。
調べるキーワードもわからないのがなかなかしんどい。
その分動いたとき一番楽しいですが。

builder.Services.AddHttpClient("HatenaEntry", client =>
{
    client.BaseAddress = new Uri("https://blog.hatena.ne.jp/<user name>/<domain name>/atom/");
    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(
        "Basic",
        Convert.ToBase64String(Encoding.UTF8.GetBytes("<user name>:<API Key>"))
        );
});

BASIC認証はこんな感じで動くらしいです。
ほかにもWSSE認証とかいろいろ種類あるらしいですが今はもうおなか一杯です。

クライアント側の実装

クライアント側は、今回はパースして表示するだけですがもっとWebAssemblyっぽさを体験するためにやりたいことが貯まってます。

Microsoft.SyndicationFeed.ReaderWriter

今回取得したデータはATOMという形式?らしく、RSSとかFeedとかの仲間らしいです。
そっちも知らんけど。
で、その形式を読み書きしてくれるパッケージを見つけたので取得してインストールしておきます。
Microsoft.SyndicationFeed.ReaderWriterです。

ページの追加

ここも前回と変わらずなので割愛します。

読み込み処理の実装

GitHubのサンプルのほぼコピペですが、相当使いにくいです。

private List<AtomEntry> _items;
private async void OnClick(MouseEventArgs e)
{
    var stream = await _client.GetStreamAsync("api/HatenaEntry");

    _items = new List<AtomEntry>();
    using (var xmlReader = XmlReader.Create(stream, new XmlReaderSettings() { Async = true }))
    {
        var feedReader = new AtomFeedReader(xmlReader);

        while (await feedReader.Read())
        {
            switch (feedReader.ElementType)
            {
                // Read category
                case SyndicationElementType.Category:
                    ISyndicationCategory category = await feedReader.ReadCategory();
                    break;

                // Read Image
                case SyndicationElementType.Image:
                    ISyndicationImage image = await feedReader.ReadImage();
                    break;

                // Read Item
                case SyndicationElementType.Item:
                    if (await feedReader.ReadItem() is AtomEntry entry)
                    {
                        _items.Add(entry);
                    }
                    break;

                // Read link
                case SyndicationElementType.Link:
                    ISyndicationLink link = await feedReader.ReadLink();
                    break;

                // Read Person
                case SyndicationElementType.Person:
                    ISyndicationPerson person = await feedReader.ReadPerson();
                    break;

                // Read content
                default:
                    ISyndicationContent content = await feedReader.ReadContent();
                    break;
            }
        }
    }
}

出来上がったもの

作成中のこの記事まで拾ってきてくれてるし、全記事取得するにはもうひと手間いりそうですが、とりあえず取得できました。

おしまい

次以降は、この取得したデータに対してフィルタかけたりデータベース化したりと、WebAssembly側に負荷を与えていこうと思います。

プライバシーポリシー


d払いポイントGETモール