A function oriented, happy way to call Google APIs from Clojure/Script.
TODO: The ClojureScript part
Everybody wants to be a bodybuilder, but nobody wants to lift no heavy-ass weights.
-- Ronnie Coleman
Everybody wants to be a data savant, but nobody wants to call no tricksy-doody APIs.
Making a request is easy - clj-http
.
(Side note: v3 has changed quite a lot!)
But there is a lot more to it:
Despite this, web APIs are often described as easy. Companies like to pretend it's easy and users like to imagine that it's easy. Nobody talks about the hard parts. This situation often ends with frustration and failure.
Part of the difference between Amazonica and Cognitect is trying to make you think it's a function call, but it's not! Stop pretending. A client with stateful stuff. Call request with a data object.
Getting stuff out. Return or something else?
TODO: insert diagrams
App -secret-> Google
Google -access-> User
User -access-> App
...
App -secret-> Google
...
Google -access-> User
...
User -access-> App
...
Poor API usage:
API usage is often a last resort.
Companies don't want you to use their API! Their priority is to prevent overuse (quotas) and misuse (auth).
API libraries are often out of date, and rarely address user problems. Never concerned with paging or throttling.
A library!
Generate code from the webservice description document (A big JSON file).
TODO: I like the big JSON file, do other companies have these (AWS?)
TODO: Can it be made compatible with things like Swagger?
TODO: Compare, contrast, and learn from https://github.com/cognitect-labs/aws-api
Makes consuming the API a pleasure! I can use my IDE features like "help" and "autocomplete" to quickly make requests with confidence that I got them right.
But there is value in having EVERYTHING be data (we can have both).
Automatically release schema changes?
Oauth2
Credential lookup (looks for secret.json etc... is there a way to encourage encrypting credentials?)
Dynamic var?
There's already a good throttling library (but does it allow rate maximization)? Make it easy to use.
Dynamic var?
There's a retry library, is it enough?
This is maybe just error handling and rate maximization? Or a task system? Or something else?
Originally I chose to follow the api organization as closely as possible, but upon reflection I think it would be better to collect resources:
happygapi.youtube.videos/list$
vs happygapi.youtube/videos-list
list
, get
etc.This could be a non-breaking change by generating BOTH, but I think that would be confusing. Given there probably aren't many users, I plan to just break this.
Pass auth
to every call, or use a global?
I originally chose to pass it to every call, the proper functional choice. But upon reflection I'd rather it be a dynamically bound function.
This could be a non-breaking change by generating BOTH, but I think that would be confusing. Given there probably aren't many users, I plan to just break this.
Should really be a separate library.
This could be a non-breaking change by generating BOTH, but I think that would be confusing. Given there probably aren't many users, I plan to just break this.
Originally some default scopes were included for convenience. But they are arbitrary and bad. I plan to break this.
These seem like they would be helpful
Probably not? Maybe worth discussion.
Can you improve this documentation?Edit on GitHub
cljdoc builds & hosts documentation for Clojure/Script libraries
Ctrl+k | Jump to recent docs |
← | Move to previous article |
→ | Move to next article |
Ctrl+/ | Jump to the search field |