atproto SDK: general-purpose API client (#900)
This is a more-protocol-complete replacement for `xrpc.Client`. I've
iterated on the overall design a couple times and feel pretty confident
about this implementation. Features:
- `APIClient` for use with XRPC HTTP requests
- pluggable `AuthMethod` abstraction, with basic implementations for
admin auth and password auth sessions (other auth methods, like OAuth
and inter-service auth, will be separate packages)
- reusable `APIError` and `APIRequest` types
- handle corner-cases like retryable request bodies when auth method
needs to re-send requests
- test coverage
Design notes for reviewers:
- should this package be named `atproto/atclient` instead of
`atproto/client`? "client" is such a generic term
- plan is to have `atproto/auth` with both server and client
implementations of service auth; and then `atproto/auth/oauth` with
OAuth stuff
- observability: open to adding `slog` logging if desired. I'd be
resistant to adding things like otel traces or prometheus metrics; i'd
like to keep this base type minimal in terms of dependencies. could hook
those in via `http.Client`, or a wrapper type.
- some initialization methods return just a pointer to a struct (no
error). those could be returning the struct directly; not sure what our
house style should be for that
A couple small known limitations:
- one not-frequently-used protocol feature is to return the "last
indexed" repo rev in AppView responses, to help with read-after-write
and debugging. the `Get()` and `Post()` helpers don't have an easy way
to access that; could be saved on the `APIClient` struct itself?
- with password auth, there isn't an easy to way directly call
`Logout()`. it isn't so bad to type-unpack the `APIClient.Auth` when
needed? but alternatively the `DoWithAuth` method could detect any
`deleteSession` call and use the refresh token for that (instead of
access token); then calling code would just call that method. feels a
bit "magic" though.
- some headers, like `User-Agent`, don't get passed through and included
on some special calls, like token refresh. not sure how big a deal this
is
authored by
bnewbold.net
and committed by
GitHub
be0a9b5e
294ad377