「RestSharp」を使ってC#で簡単にREST APIを操作してみる

# はじめに
本記事はC#でREST APIを簡単に操作するためのライブラリである「RestSharp」を使ってみて得た知見をまとめることを目的としています。

# RestSharpとは
REST APIをC#から簡単に操作するためのライブラリです。
C#標準のHttpClientを使うよりも手軽にREST APIを利用するための機能が搭載されています。
詳細は[こちら](https://restsharp.dev/)を参照ください。

# どれぐらい簡単に書けるのか
以前私が投稿した[C#からSlackAPIを利用してみる記事](https://qiita.com/tat_tt/items/4104f6c95e00261439fe#%E6%99%82%E9%96%93%E3%82%92%E6%8C%87%E5%AE%9A%E3%81%97%E3%81%A6%E3%83%A1%E3%83%83%E3%82%BB%E3%83%BC%E3%82%B8%E3%82%92%E5%8F%96%E5%BE%97%E3%81%99%E3%82%8B%E3%82%B5%E3%83%BC%E3%83%93%E3%82%B9)を参考に、取得数を指定してSlackAPI経由でメッセージを取得するサービスをHttpClientとRestSharpの両方を使って書いてみて、どれぐらいRestSharpでREST APIの操作が楽になるかを見ていきたいと思います。

## HttpClientを使った場合
HttpClientを使った場合は、以下のようなコードになります。
クエリパラメータを作るためにディクショナリを作り、文字列に変換したのちにAPIのURLにクエリパラメータとして連結して、GETすることでメッセージを取得しています。

```csharp
/// <summary>
/// HttpClientを使った場合のSlackApiサービス
/// </summary>
internal static class SlackApiServiceFromHttpClient
{
    #region 定数

    /// <summary>
    /// アクセストークン用のクエリパラメータ名
    /// </summary>
    private const string _AccessTokenQueryParameterName = "token";

    /// <summary>
    /// チャンネルID用のクエリパラメータ名
    /// </summary>
    private const string _ChannelIdQueryParameterName = "channel";

    /// <summary>
    /// 取得メッセージ数用のクエリパラメータ名
    /// </summary>
    private const string _MessageCountQueryParameterName = "limit";

    #endregion

    #region フィールド

    /// <summary>
    /// HttpClient
    /// </summary>
    private static readonly HttpClient _HttpClient = new HttpClient();

    #endregion

    #region 公開サービス

    /// <summary>
    /// メッセージを取得する
    /// </summary>
    /// <param name="accessToken">アクセストークン</param>
    /// <param name="channelId">チャンネルID</param>
    /// <param name="messageCount">取得するメッセージ数</param>
    /// <returns>取得メッセージ一覧</returns>
    public static async Task<IEnumerable<Message>> GetMessages(string accessToken, string channelId, int messageCount)
    {
        var messages = new List<Message>();

        // クエリパラメータを作成するためにディクショナリを作成
        // ディクショナリのKeyがクエリパラメータ名、ディクショナリのValueがクエリパラメータの値
        var parameters = new Dictionary<string, string>()
        {
            { _AccessTokenQueryParameterName, accessToken},
            { _ChannelIdQueryParameterName, channelId},
            { _MessageCountQueryParameterName, messageCount.ToString()},
        };

        try
        {
            // クエリパラメータを作成し、文字列で読み出す
            var parametersString = await new FormUrlEncodedContent(parameters).ReadAsStringAsync();
            // 読みだしたクエリパラメータを使ってリクエストURLを作成する。
            var requestBaseUrl = "https://slack.com/api/conversations.history";
            var requestUrl = $"{requestBaseUrl}?{parametersString}";
            var response = await _HttpClient.GetAsync(requestUrl).ConfigureAwait(false);
            // レスポンスのコンテンツをstringで読み出す
            var responseBodyString = await response.Content.ReadAsStringAsync();
            // 読みだしたJsonを、オブジェクトにデシリアライズする
            var getMessages = JsonConvert.DeserializeObject<MessageList>(responseBodyString);

            // 戻り値用のメッセージ一覧を作成
            foreach (var messageResponce in getMessages.Messages)
            {
                // 本文を設定
                var message = new Message()
                {
                    Text = messageResponce.Text
                };

                messages.Add(message);
            }

            return messages;
        }
        catch
        {
            return messages;
        }
    }

    #endregion
}
```

## RestSharpを使った場合
RestSharpを使った場合は、以下のようなコードになります。

```csharp
/// <summary>
/// RestSharpを使った場合のSlackApiサービス
/// </summary>
internal static class SlackApiServiceFromRestSharp
{
    #region 定数

    /// <summary>
    /// アクセストークン用のクエリパラメータ名
    /// </summary>
    private const string _AccessTokenQueryParameterName = "token";

    /// <summary>
    /// チャンネルID用のクエリパラメータ名
    /// </summary>
    private const string _ChannelIdQueryParameterName = "channel";

    /// <summary>
    /// 取得メッセージ数用のクエリパラメータ名
    /// </summary>
    private const string _MessageCountQueryParameterName = "limit";

    #endregion

    #region 公開サービス

    /// <summary>
    /// メッセージを取得する
    /// </summary>
    /// <param name="accessToken">アクセストークン</param>
    /// <param name="channelId">チャンネルID</param>
    /// <param name="messageCount">取得するメッセージ数</param>
    /// <returns>取得メッセージ一覧</returns>
    public static async Task<IEnumerable<Message>> GetMessages(string accessToken, string channelId, int messageCount)
    {
        var messages = new List<Message>();

        // クライアント作成
        var client = new RestClient("https://slack.com/api/conversations.history");

        // クエリパラメータ作成
        var request = new RestRequest();
        request.AddQueryParameter(_AccessTokenQueryParameterName, accessToken);
        request.AddQueryParameter(_ChannelIdQueryParameterName, channelId);
        request.AddQueryParameter(_MessageCountQueryParameterName, messageCount.ToString());

        try
        {
            var getMessageList = await client.GetAsync<MessageList>(request);

            // 戻り値用のメッセージ一覧を作成
            foreach (var messageResponce in getMessageList.Messages)
            {
                // 本文を設定
                var message = new Message()
                {
                    Text = messageResponce.Text
                };

                messages.Add(message);
            }

            return messages;
        }
        catch
        {
            return messages;
        }
    }

    #endregion
}
```
大きな違いとしては、クエリパラメータを作成してからGETするまでのコード量です。
先述したようにHttpClientを使った場合は、クエリパラメータを作るためにディクショナリを作り、文字列に変換したのちにAPIのURLにクエリパラメータとして連結して、GETすることでメッセージを取得しています。一方RestSharpを使った場合は、クエリパラメータをメソッド経由で追加して、その後GETするだけでメッセージを取得しています。
個人的にはクエリパラメータが直感的なメソッドで登録できる点が使いやすいと感じました。

# RestSharpの利用方法
RestSharpはNugetで取得可能なライブラリなので、VisualStudioでプロジェクトを右クリックし、[Nugetパッケージの管理]から開くダイアログでRestSharpと検索して、インストールすれば利用可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/452292/66ca6ed1-c3c6-c2ac-4476-9ae4d42b13fd.png)

# まとめ
本記事ではRestSharpを使ってみて、HttpClientと比べて使いやすい点についてまとめました。
単純なREST API操作を例にしましたが、HttpClientと比べてメソッド経由で直感的にAPIを操作できると感じました。
今後C#でREST APIを操作する際にはぜひ使いたいと思いました。