GitHub Pages is an easy, free way to make data available through an API.
What is GitHub Pages?
Any repo, user and organization on GitHub can have its own static website hosted by GitHub for free.
Many projects use it to host documentation websites but it can host any kind of content. Instead of hosting html, you can host JSON files.
Enable it
- Go to the home page of a repo you have admin access to
- Go to the "Settings" tab
- Scroll down to the "GitHub Pages" section
- Set "Source" to "master branch"
Wait a few seconds and then go to https://<username>.github.io/<repo name>
. Any files on the master branch in the repo are now served at that url.
CORS header
GitHub graciously includes a wildcarded CORS header in the responses.
This is key because now any webapp can pull data directly from the API. No backend servers are needed.
Url and routes
The "base" url is made from your GitHub username (or organization name) and the repo name:
https://<username or org name>.github.io/<repo name>
Any url path after that is determined by directory structure of the repo.
A repo called "restaurant" with this directory structure
└── locations
├── los-angeles
│ └── menu.json
└── new-york
└── menu.json
will have these routes
https://<username>.github.io/restaurant/locations/los-angeles/menu.json
https://<username>.github.io/restaurant/locations/new-york/menu.json
What datasets?
This kind of API is best suited for datasets that are read-only and mostly static.
The API is updated by git push
so highly dynamic data like stock prices would be difficult. Routes that appear to have ids in them are really just directories or files, so all of the data must be known ahead of time.
Handling 404s
When a non-existent route is accessed, GitHub serves 404.html
, if it exists at the root of the repo. Otherwise it serves a default 404 page. Sending html is not ideal for a JSON API but the response status code is probably the most important thing for clients, and that is set correctly.
I make my 404.html
look like
404 Not Found
Please see <url to API docs>
Maybe that will help a confused developer figure out what they're doing wrong.
Client
A really basic browser client for an API like this could be
function hitApi(url, callback) {
var req = new XMLHttpRequest();
req.addEventListener('load', onLoad);
req.addEventListener('error', onFail);
req.addEventListener('abort', onFail);
req.open('GET', url);
req.send();
function onLoad(event) {
if (req.status >= 400) {
onFail(event);
} else {
var json = JSON.parse(this.responseText);
callback(null, json);
}
}
function onFail(event) {
callback(new Error('...'));
}
}
with usage
hitApi('url here', function(error, data) {
if (error) {
console.log('there was an error', error);
} else {
console.log('data is', data);
}
});