自由にできる非公式なMackerelクライアントライブラリを持っとくと便利そうな予感を得たので、まずは素朴にちょいと素振りして傾向と対策の勘所を。
取り合えずサービスの上3つからお試し。
open System open System.Net open System.Net.Http open System.Text open System.Text.Json type NewService = { name: string; memo: string } type Service = { name: string memo: string roles: string list } type Services = { services: Service list } let baseUrl = "https://api.mackerelio.com" let key = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" let run task = task |> Async.AwaitTask |> Async.RunSynchronously |> function | Ok res -> printfn "%A" res | Error err -> printfn "%s" err let getServices (baseUrl: string) (key: string) = task { let uri = Uri $"{baseUrl}/api/v0/services" use request = new HttpRequestMessage(HttpMethod.Get, uri) request.Headers.Add("X-Api-Key", key) use httpClient = new HttpClient() let! response = httpClient.SendAsync request return! match response.StatusCode with | HttpStatusCode.OK -> task { let! content = response.Content.ReadAsStreamAsync() let! services = JsonSerializer.DeserializeAsync<Services>(content) return Ok services } | e -> task { return Error $"Unexpected response: {e}" } } getServices baseUrl key |> run let createService (baseUrl: string) (key: string) (service: NewService) = task { let json = JsonSerializer.Serialize service use content = new StringContent(json, Encoding.UTF8, "application/json") let uri = Uri $"{baseUrl}/api/v0/services" use request = new HttpRequestMessage(HttpMethod.Post, uri, Content = content) request.Headers.Add("X-Api-Key", key) use httpClient = new HttpClient() let! response = httpClient.SendAsync request return! match response.StatusCode with | HttpStatusCode.OK -> task { let! content = response.Content.ReadAsStreamAsync() let! service = JsonSerializer.DeserializeAsync<Service>(content) return Ok service } | HttpStatusCode.BadRequest -> task { return Error "Invalid service name" } | HttpStatusCode.Forbidden -> task { return Error "Unpermitted request" } | e -> task { return Error $"Unexpected response: {e}" } } { name = "Service99"; memo = "めも" } |> createService baseUrl key |> run let deleteService (baseUrl: string) (key: string) (serviceName: string) = task { use content = new StringContent("", Encoding.UTF8, "application/json") let uri = Uri $"{baseUrl}/api/v0/services/{serviceName}" use request = new HttpRequestMessage(HttpMethod.Delete, uri, Content = content) request.Headers.Add("X-Api-Key", key) use httpClient = new HttpClient() let! response = httpClient.SendAsync request return! match response.StatusCode with | HttpStatusCode.OK -> task { let! content = response.Content.ReadAsStreamAsync() let! service = JsonSerializer.DeserializeAsync<Service>(content) return Ok service } | HttpStatusCode.Forbidden -> task { return Error "Unpermitted request" } | HttpStatusCode.NotFound -> task { return Error "Service not found" } | e -> task { return Error $"Unexpected response: {e}" } } "Service99" |> deleteService baseUrl key |> run
サービスの削除でボディ無しでもContent-Type: application/json
が無いとBad Request
返ってくるのにちょっとハマった。
なるほど把握した。ボチボチやってこ。