前回で傾向が分かったので対策する。
ライブラリっぽい部分。
namespace Mackerel open System.Net open System.Text.Json.Serialization open FsHttp type Options = { BaseUri: string; ApiKey: string } module HttpClient = let send<'t> request = async { let! response = request |> Request.sendAsync match response.statusCode with | HttpStatusCode.OK -> let! data = response |> Response.deserializeJsonAsync<'t> return Ok data | e -> return Error e } let get<'t> (path: string) param options = http { GET $"{options.BaseUri}{path}" header "X-Api-Key" options.ApiKey query param } |> send<'t> let post<'t> (path: string) param options = http { POST $"{options.BaseUri}{path}" header "X-Api-Key" options.ApiKey body jsonSerialize param } |> send<'t> let put<'t> (path: string) param options = http { PUT $"{options.BaseUri}{path}" header "X-Api-Key" options.ApiKey body jsonSerialize param } |> send<'t> let delete<'t> (path: string) options = http { DELETE $"{options.BaseUri}{path}" header "X-Api-Key" options.ApiKey body json "" } |> send<'t> type Org = { [<JsonPropertyName("name")>] Name: string } module Org = let get = HttpClient.get<Org> "/api/v0/org" [] type Service = { [<JsonPropertyName("name")>] Name: string [<JsonPropertyName("memo")>] Memo: string [<JsonPropertyName("roles")>] Roles: string list } module Service = let findAll = HttpClient.get<{| services: Service list |}> "/api/v0/services" [] type CreateParam = { [<JsonPropertyName("name")>] Name: string [<JsonPropertyName("memo")>] Memo: string } let create (param: CreateParam) = HttpClient.post<Service> "/api/v0/services" param let delete (serviceName: string) = HttpClient.delete<Service> $"/api/v0/services/{serviceName}" let listMetricNames (serviceName: string) = HttpClient.get<{| names: string list |}> $"/api/v0/services/{serviceName}/metric-names" [] type User = { [<JsonPropertyName("id")>] ID: string [<JsonPropertyName("screenName")>] ScreenName: string [<JsonPropertyName("email")>] Email: string [<JsonPropertyName("authority")>] Authority: string [<JsonPropertyName("isInRegistrationProcess")>] IsInRegistrationProcess: bool [<JsonPropertyName("isMFAEnabled")>] IsMFAEnabled: bool [<JsonPropertyName("authenticationMethods")>] AuthenticationMethods: string list [<JsonPropertyName("joinedAt")>] JoinedAt: int64 } module User = let findAll = HttpClient.get<{| users: User list |}> "/api/v0/users" [] let delete (userId: string) = HttpClient.delete<User> $"/api/v0/users/{userId}"
アプリケーションっぽい部分。
open Mackerel let run t = t |> Async.RunSynchronously |> printfn "%A" let options = { BaseUri = "https://api.mackerelio.com" ApiKey = "*********************************************" } module Org = open Org get options |> run module Service = open Service findAll options |> run ({ Name = "Service888" Memo = "Service 888" }, options) ||> create |> run ("Service888", options) ||> listMetricNames |> run ("Service888", options) ||> delete |> run module User = open User findAll options |> run
FsHttp 便利~。