Don’t stress about web APIs
I’ve had to deal with a bunch of Web APIs as of late, and because I was getting fed up with the boilerplate I’ve put together RestClient.jl, which aims to make interfacing with Web APIs as simple as reasonably possible, with sensible out-of-the-box behaviour.
To that end, it takes care of URI encoding and rate limiting, comes with basic debugging utilities, and makes serialisation/deserialisation as simple as slapping @jsondef
/ @xmldef
in front of a struct (with an optional syntax for specifying what JSON/XML element should map to a field).
A great place to start is by looking at the tutorial, but here’s an example from the readme for what it takes to wrap a JSON API:
using RestClient, JSON3
@globalconfig RequestConfig("https://api.sampleapis.com/coffee")
@jsondef struct Coffee
title::String
description::String
ingredients::Vector{String}
image::String
id::Int
end
@endpoint hot() -> "hot" -> Vector{Coffee}
@endpoint iced() -> "iced" -> Vector{Coffee}
To give an XML example too:
using RestClient, XML
@globalconfig RequestConfig("https://boardgamegeek.com/xmlapi2")
@xmldef struct SearchItem
type."@type"::Symbol
id."@id"::Int
name."name[1]/@value"::String
year."yearpublished[1]/@value"::Union{Int, Nothing}
end
@xmldef struct SearchResponse <: ListResponse{SearchItem}
items."items[1]/item"::Vector{SearchItem}
end
@endpoint search(query::String) -> "search?{query}" -> SearchResponse
All these macros are shorthand for creating methods and types for the RestClient request/response process, which looks a bit like this:
Invocation: apido(x) -> perform(Request(...)):
╭─╴config╶────────────────────────────╮
│ ╎ │
│ ╎ ╭─▶ responsetype ╾─────┼────────────────┬──▶ dataformat ╾───╮
Request╶─┤ ╰╶╶╶╶╶╶╶╶│ │ ╰─────────╮ │
│ ├─▶ pagename ╾───╮ │ ┌┄┄┄┄debug┄┄┄┐ │ ╭──────╯
│ │ ├──▶ url ╾─┬─━─▶ request ╾━┬─▶ interpret ╾──▶ data
├─╴endpoint╶───┼─▶ parameters ╾─╯ │ │ │
│ │ │ │ ╭─────╯
│ ├─▶ parameters ╾────────────┤ ╰─────────╮ │
│ │ │ postprocess ╾──▶ result
│ *╰─▶ payload ─▶ writepayload╶╯ │
│ ╰─▶ dataformat ╾╯ │
╰─────────┬────────────────────────────────────────────────────────────╯
╰────▶ validate (before initiating the request)
* Only for POST requests ╶╶ Optional first argument
At this point I’m pretty happy with it, but before I register the package I’d like to check to see if anybody else writing (or thinking about writing) API clients has thoughts on the design.
I like that it’s useful for me, I’d love it if it was useful to more people too