Introduction
Welcome to the Openframe JavaScript Client! You can use this lib to access Openframe REST API endpoints, which can be used to fetch and update artworks, frames, and profile information for authenticated users.
At present we only have this JavaScript client library, but you’re welcome to use any language to interact with the API directly.
All of the methods of the JS client return Promises which are resolved with the parsed response body or are rejected with an error message.
Initializing the JS Client
import OF from 'openframe-jsclient';
// use default openframe server, openframe.io
const OF = new OF();
// to use a different server, pass option to constructor
const OF = new OF({
api_base: 'http://localhost:8888/api'
});
Import the Javascript client class and create a new instance, optionally passing configuration options.
Configuration Options
Option | Default | Description |
---|---|---|
api_base | https://api.openframe.io/ | The base URL where the API is located |
Authentication / Authorization
Although some Openframe data is public and can be retrieved via unauthenticated access, the API requires an authenticated user’s access token to be supplied with requests in order to manipulate a user’s data. An access token can be obtained by hitting the login
endpoint and providing a valid username (or email) and password.
Once obtained, the access token may be included in requests as a query param:
GET https://api.openframe.io/v0/user/12345/owned_frames?access_token=wtu2jsJYZTO8ZqjGokR1ejznxCw4Qd0hACFo50GXyx3eGcVNNroccDWHZHmHVXKn
or in an Authentication header:
Authentication: wtu2jsJYZTO8ZqjGokR1ejznxCw4Qd0hACFo50GXyx3eGcVNNroccDWHZHmHVXKn
As noted below, after successful login, the JS client manages storage and inclusion of the header (in browsers with localStorage available).
Log in
This assumes you’ve got an instantiated OF client.
OF.users.login({'username': 'test', 'password': 'test'})
.then(token => {
console.log(token);
});
// or
OF.users.login({'email': 'test@test.com', 'password': 'test'})
.then(token => {
console.log(token);
});
If valid credentials are passed, the resolved token object, looks like this, where “id” is the actual access token value:
{
"id": "wtu2jsJYZTO8ZqjGokR1ejznxCw4Qd0hACFo50GXyx3eGcVNNroccDWHZHmHVXKn",
"ttl": 1209600,
"created": "2016-12-05T03:45:55.936Z",
"userId": "56c47fba45e503657a51bebc"
}
On success, the login
endpoint responds with an access token that is valid for two weeks or until explicity destroyed via logout. The token is presented as the id
value of response body, and must be supplied with subsequent requests on behalf of the logged in user.
If localStorage is present (i.e. the browser), the JS client automatically saves the access token to localStorage and includes it in subsequent responses.
Log out
Calling logout
will destroy the access token on the server and, if present, clear it from localStorage. Successful logout will result in a 204 no content response and resolve the Promise. If there is any problem destroying the access token on the server, the promise will be rejected with an error.
OF.users.logout()
.then(() => {
// success, no response body
})
.catch(error => {
console.log(error);
});
Users
Fetch a list of Users
OF.users.fetch(filter)
.then(users => {
// do something with users
});
The above users array is structured like this:
[
{
"full_name": "Sol Lewitt",
"username": "slewitt",
"created": "2016-02-17T14:12:10.463Z",
"id": "56c47fba45e503657a51bebd",
"modified": "2016-02-17T14:12:10.463Z"
},
{
"full_name": "Peter Pan",
"username": "ppan",
"created": "2016-02-17T14:12:10.560Z",
"id": "56c47fba45e503657a51bebc",
"modified": "2016-02-17T14:12:10.560Z"
},
{
"full_name": "Missy Elliot",
"username": "melliot",
"created": "2016-02-17T14:12:10.666Z",
"id": "56c47fba45e503657a51bebe",
"modified": "2016-02-17T14:12:10.666Z"
}
]
This endpoint retrieves a list of users. At present, limited information is public for all Openframe users.
Arguments
Arg | Default | Description |
---|---|---|
filter | {} | A filter config object |
Fetch a User by ID
OF.users.fetchById()
.then(user => {
// user is currently authenticated user
});
OF.users.fetchById("56c47fba45e503657a51bebd")
.then(user => {
// do something with user
});
The above user object is structured like this:
{
"full_name": "Sol Lewitt",
"username": "slewitt",
"created": "2016-02-17T14:12:10.463Z",
"id": "56c47fba45e503657a51bebd",
"modified": "2016-02-17T14:12:10.463Z"
}
This method retrieves a specific user by ID.
If no ID is passed, it defaults to ‘current’, which returns the currently authenticated user.
Arguments
Arg | Default | Description |
---|---|---|
ID | 'current’ | A user ID |
Fetch a User by username
OF.users.fetchByUsername("slewitt")
.then(user => {
/* user looks like
{
"full_name": "Sol Lewitt",
"username": "slewitt",
"created": "2016-02-17T14:12:10.463Z",
"id": "56c47fba45e503657a51bebd",
"modified": "2016-02-17T14:12:10.463Z"
}
*/
});
This method retrieves a specific user by Username.
Arguments
Arg | Default | Description |
---|---|---|
username | none | A username |
Frames
Fetch all current User’s frames
Artwork
Fetch a list of Artworks
OF.artwork.fetch(filter)
.then(artworks => {
// do something with artworks
});
The above artworks array is structured like this:
[
{
"title": "unknown-1471551583623.frag",
"is_public": true,
"url": "https://thebookofshaders.com/log/160818203933.frag",
"thumb_url": "https://thebookofshaders.com/log/160818203933.png",
"author_name": "unknown",
"required_extensions": {},
"format": "openframe-glslviewer",
"id": "57b61d12c0006da8310e9143",
"ownerId": "57b61cf8c0006da8310e9141",
"created": "2016-08-18T20:39:46.662Z",
"modified": "2016-08-18T20:39:46.662Z"
},
{
"title": "Nutrition Facts",
"is_public": true,
"url": "http://streetkonect.com/nutritionfacts",
"thumb_url": "http://streetkonect.com/nutritionfacts/nf4b.jpg",
"author_name": "Leah Valle",
"required_extensions": {},
"format": "openframe-website",
"id": "57a85d5bc0006da8310e906b",
"ownerId": "57a85cf2c0006da8310e9069",
"created": "2016-08-08T10:22:19.405Z",
"modified": "2016-08-08T10:22:19.405Z"
}
]
This endpoint retrieves a list of Artworks. If called by an unauthenticated user, the list will include only public Artworks. If called by an authenticated user, private Artworks which the user has added will also be present in the response.
Fetch an Artwork by ID
Filtering queries
// an example filter for an OF.users.fetch(filter)
let filter = {
fields: ['username', 'id', 'website'], // fields to include
include: 'created_artwork', // include a relation in the result
limit: 10, // limit the number of results
skip: 10, // skip a number of results
order: 'username ASC', // result order direction, ASC or DESC
where: { // filter by field data
username: {
like: 'abc' // lots of operator options
}
},
}
All of the fetch
methods can take an optional filter
config object, which allows filtering of the query results. Whenever available, it takes the form shown on the right.
Errors
The Kittn API uses the following error codes:
Error Code | Meaning |
---|---|
400 | Bad Request – Your request sucks |
401 | Unauthorized – Your API key is wrong |
403 | Forbidden – The kitten requested is hidden for administrators only |
404 | Not Found – The specified kitten could not be found |
405 | Method Not Allowed – You tried to access a kitten with an invalid method |
406 | Not Acceptable – You requested a format that isn’t json |
410 | Gone – The kitten requested has been removed from our servers |
418 | I’m a teapot |
429 | Too Many Requests – You’re requesting too many kittens! Slow down! |
500 | Internal Server Error – We had a problem with our server. Try again later. |
503 | Service Unavailable – We’re temporarially offline for maintanance. Please try again later. |