Menu

API

API allows elements to trigger actions on a server

Already Knows Your UI

Attach an API event to an input, by default, it willn occur oninput. Attach an API event to a button, onclick. API also ties API state to UI state: rate throttling, class adjustments for active, loading, disabled, syncing between multiple elements, and more.

Deal with resources not URLs

Use API actions like 'follow user' and not server urls in your code. Centrally manage your entire API making sure you aren't caught modifying urls across your codebase. Define your endpoints using an intuitive templating system that automatically passes data found in your UI.

State Management

API helps your UI keep track of server events, and is designed to work with Semantic's state naming conventions to track loading, disabled, and active states.

This allows you to do things like set maximum and minimum UI load times, toggle between text states, and sync UI states between multiple elements with the same API actions.

Server Traces For Humans

View your API request as it occurs in your web console, get errors if required url variables are missing, and useful performance metrics.

Stevie Feliciano
Joined in Sep 2014

Creating an API

Working with named URLs:

API works best by defining a "vocabulary" of API actions which interface elements can query. These named URLs are referred to internally as API actions, and make up all the triggerable behaviors on the server.

These actions are stored as templated URLs which include templated parameters that can be substituted at run-time.

URLs listed in your API can include required parameters and optional parameters which may be adjusted for each call.

Required Parameters
Uses format {variable}
Will abort the request if they cannot be found.
/* Two required variables */ $.fn.api.settings.api = { 'get followers' : '/followers/{id}?results={count}', };
Optional Parameters
Uses format {/variable}
Will not abort the request if they cannot be found.
Will be removed from the url automatically if not available.
Any preceding slash before an optional parameter will be removed from the URL, allowing you to include them in resource paths.
/* One required, one optional variable */ $.fn.api.settings.api = { 'get followers' : '/followers/{id}/{/sort}', };

Creating your API

You should define your endpoints once in your application. Usually this is done in a central configuration file included on each page.

Keeping your endpoints defined in one place makes sure when you update your application you will only need to update a single location with new URLs

/* Define API endpoints once globally */ $.fn.api.settings.api = { 'get followers' : '/followers/{id}?results={count}', 'create user' : '/create', 'add user' : '/add/{id}', 'follow user' : '/follow/{id}', 'search' : '/search/?query={value}' };

Basic Usage

Named API actions are not required to use $.api you can also manually specify the url for a request and use the same templating:

$('.search.button') .api({ url: 'http://www.google.com?q={value}' }) ;

Querying API Actions

Open Your Web Console

The following examples work best while viewing logs in your web console. This experienced is optimized for Firebug, but will also appear in webkit browsers with minor issues.

API requests for the following demos have been faked using SinonJS to avoid rate throttling from public APIs. No actual data is returned.

Attaching API Events

API events are triggered by attaching named actions to elements on your page. These actions look up named endpoints in your API translating templated values from your element for each call.

Any element can have an API action attached directly to it. By default the action will occur on the most appropriate event for the type of element. For example a button will call your server onclick, an input oninput, or a form onsubmit.

API actions and data can be specified in javascript on initialization

// translates '/follow/{id}' to 'follow/22' $('.follow.button') .api({ action: 'follow user', urlData: { id: 22 } }) ;
Or

API actions and data can also be specified in metadata:

// also calls '/follow/22' $('.follow.button') .api() ;

Specifying DOM Events

If you need to override what action an API event occurs on you can use the on parameter.

$('.follow.button') .api({ action: 'follow user', on: 'mouseenter' }) ;

Calling Immediately

If you require API action to occur immediately use on: 'now'. This will still trigger the same state updates to the invoked element, but will occur immediately.

$('.follow.button') .api({ action: 'follow user', on: 'now' }) ;

Keep in mind passing a new settings object will destroy the previous instance, and all its settings and events. If you want to preserve the previous instance, you can trigger a new request with the the query behavior

// set-up API button with events $('.follow.button') .api({ action: 'follow user' }) ; // do an immediate query $('.follow.button') .api('query') ;

Setting-up Requests

URL Variables

If your API urls include templated variables they will be replaced during your request by one of four possible ways (listed in order of inheritance).

Automatically Routed Data

Some special values will be automatically replaced if specified in URL actions

Variable Description Available for
text current text value of element All elements
value current input value of element Input elements
$.fn.api.settings.api.search = '/search/?query={value}'; $('.search input') .api({ action: 'search', // what receives state class names stateContext: '.ui.input' }) ;

Data Specified in Data Attributes

You can include url values as html5 metadata attributes

This is often easiest to include unique url data for each triggering element, for example, many follow buttons will trigger the same endpoint, but each will have its own user id.

Only variables specified in your API's URL will be searched for in metadata.
Follow Sally
Follow Jenny
// requests different urls for each button $('.follow.button') .api({ action: 'follow user' }) ;

Data Specified in Javascript

URL variable, and GET/POST data can be specified at run-time in the javascript object

$('.follow.button') .api({ action : 'follow user', method : 'POST', // Substituted into URL urlData: { id: 22 }, // passed via POST data: { name: 'Joe Henderson' } }) ;

Adjusting Request in Before Send

All run settings, not just url data, can be adjusted in a special callback beforeSend which occurs before the API request is sent.

An additional callback beforeXHR lets you modify the XHR object before sending. This is different than beforeSend which is used to modify settings before send.
$('.follow.button') .api({ action: 'follow user', beforeSend: function(settings) { settings.urlData = { id: 22 }; return settings; } beforeXHR: function(xhr) { // adjust XHR with additional headers xhr.setRequestHeader ('Authorization', 'Basic XXXXXX'); } }) ;

Cancelling Requests

BeforeSend can also be used to check for special conditions for a request to be made. It the beforeSend callback returns false, the request will be cancelled.

// set somewhere in your code window.isLoggedIn = false; $('.follow.button') .api({ action: 'follow user', beforeSend: function(settings) { // cancel request return isLoggedIn; } }) ;

Sending Data

Serializing Form Data

Calling API on any element inside of a form, will automatically include serialized form content in your request when using a special setting serializeForm, or using a form as the stateContext.

Unlike jQuery's serialize, Form data is serialized as a javascript object.

Using serializeForm requires including macek's serialize object converter.
Benefits of Structured Data
  • Serialized Form Data can be modified in javascript in beforeSend
  • You can send structured data by using form names like name="name[first]" in your form
  • Form data will automatically be converted to their javascript equivalents, for instance, checkboxes will be converted to boolean values.
  • Submit
    $('form .submit.button') .api({ action: 'create user', serializeForm: true, beforeSend: function(settings) { // form data is editable in before send if(settings.data.username == '') { settings.data.username = 'New User'; } // open console to inspect object console.log(settings.data); return settings; } }) ;

Specifying Data in Javascript

POST or GET data can be specified directly when initializing an API requests, or included in beforeSend

$('.form .submit') .api({ action: 'create user', serializeForm: true, // arbitrary POST/GET same across all requests data: { session: 22 }, // POST/GET data can be modified PER request beforeSend: function(settings) { // cancel request if no id if( !$(this).data('id') ) { return false; } settings.data.userID = $(this).data('id'); return settings; } }) ;

Server Responses

Response Callbacks

Succesful responses from the server will trigger onSuccess, invalid results onFailure.

onError will only trigger on XHR errors (except due to page navigation like clicking a link), but not invalid JSON responses.

$('.follow.button') .api({ successTest: function(response) { return response.success || false; } onSuccess: function() { // valid response and response.success = true }, onFailure: function() { // valid response but response.success = false }, onError: function() { // invalid response }, onAbort: function() { // user cancelled request } }) ;

Determining JSON Success

API has special success conditions for JSON responses. Instead of providing success and failure callbacks based on the HTTP response of the request. A request is considered succesful only if the server's response tells you the action was successful. The response is passed to a validation test successTest which can be used to check the JSON for a valid response.

For example you might expect all successful JSON responses to return a top level property signifying the success of the response

{ "success": true, "message": "We've retreived your data from the server" "data": { // payload here } }

You can specify a success test to check for this success value. This most likely will be set globally for all API requests.

$.fn.api.settings.successTest = function(response) { if(response && response.success) { return response.success; } return false; };

Controlling State

API State Management

Many elements like button, input, and form have loading, disabled, and active states defined.

States adjust class names on the triggering element or on the element specified by settings.stateContext.

Using stateContext allows you to easily do things like, trigger a loading state on a form when a submit button is pressed.

States Included in API Module
State Description API event
loading Indicates a user needs to wait XHR has initialized
error Indicates an error has occurred XHR Request returns error (does not trigger onAbort caused by page change, or if successTest fails). Stays visible for settings.errorDuration

Coupling with State Module

Initializing an API action with the state module gives you more granular control over UI states, like setting an activated or de-activated state and the ability to adjust text values for each state:

$('.follow.button') .api({ action: 'follow user' }) .state({ text: { inactive : 'Follow', active : 'Followed', deactivate : 'Unfollow', flash : 'Added follower!' } }) .state('setting', 'onActivate', function() { $(this).state('flash text'); }) ;
States Included in State Module
State Description Occurs on
inactive Default state
active Selected state Toggled on succesful API request
activate Explains activating action On hover if inactive
deactivate Explains deactivating action On hover if active
hover Explains interaction On hover in all states, overrides activate/deactivate
disabled Indicates element cannot be interacted Triggered programatically. Blocks API requests.
flash Text-only state used to display a temporary message Triggered programatically
success Indicates user action was a success Triggered programatically
warning Indicates there was an issue with a user action Triggered programatically

Behavior

All the following behaviors can be called using the syntax:

$('.your.element') .api('behavior name', argumentOne, argumentTwo) ;
Behavior Description
query Execute query using existing API settings
add url data(url, data) Adds data to existing templated url and returns full url string
get request Gets promise for current API request
abort Aborts current API request
reset Removes loading and error state from element
was cancelled Returns whether last request was cancelled
was failure Returns whether last request was failure
was successful Returns whether last request was successful
was complete Returns whether last request was completed
is disabled Returns whether element is disabled
is loading Returns whether element is loading
set loading Sets loading state to element
set error Sets error state to element
remove loading Removes loading state to element
remove error Removes error state to element
get event Gets event that API request will occur on
destroy Removes API settings from the page and all events

API

Behavior

Default Description
on auto When API event should occur
filter
.disabled
Selector filter for elements that should not be triggerable
stateContext this UI state will be applied to this element, defaults to triggering element.
defaultData true Whether to automatically include default data like {value} and {text}
serializeForm false Whether to serialize closest form and include in request
loadingDuration 0 Minimum duration to show loading indication
errorDuration 2000 Duration in milliseconds to show error state after request error.

Request Settings

Default Description Possible Values
action Named API action for query, originally specified in $.fn.settings.api String or false
url false Templated URL for query, will override specified action String or false
urlData false Variables to use for replacement
method get Method for transmitting request to server post, get
dataType JSON Expected data type of response xml, json, jsonp, script, html, text
data {} POST/GET Data to Send with Request

Callbacks

Context Description
beforeSend(settings) initialized element Allows modifying settings before request, or cancelling request
beforeXHR(xhrObject) Allows modifying XHR object for request
onSuccess(response, element) state context Callback on response object that passed successTest
onFailure(response, element) state context Callback on response object that fails successTest
onError(errorMessage, element) state context Callback on server error from returned status code, or XHR failure.
onAbort(errorMessage, element) state context Callback on abort caused by user clicking a link or manually cancelling request
onComplete(response, element) state context Callback on request complete regardless of conditions

Module

These settings are native to all modules, and define how the component ties content to DOM attributes, and debugging settings for the module.

Default Description
name API Name used in log statements
namespace api Event namespace. Makes sure module teardown does not effect other events attached to an element.
regExp
regExp : { required: /\{\$*[A-z0-9]+\}/g, optional: /\{\/\$*[A-z0-9]+\}/g, }
Regular expressions used for template matching
selector
selector: { form: 'form' }
Selectors used to find parts of a module
className
className: { loading : 'loading', error : 'error' }
Class names used to determine element state
metadata
metadata: { action : 'action' }
Metadata used to store xhr and response promise
debug false Debug output to console
performance true Show console.table output with performance metrics
verbose false Debug output includes all internal behaviors
errors
// errors error : { beforeSend : 'The before send function has aborted the request', error : 'There was an error with your request', exitConditions : 'API Request Aborted. Exit conditions met', JSONParse : 'JSON could not be parsed during error handling', legacyParameters : 'You are using legacy API success callback names', missingAction : 'API action used but no url was defined', missingSerialize : 'Required dependency jquery-serialize-object missing, using basic serialize', missingURL : 'No URL specified for api event', noReturnedValue : 'The beforeSend callback must return a settings object, beforeSend ignored.', parseError : 'There was an error parsing your request', requiredParameter : 'Missing a required URL parameter: ', statusMessage : 'Server gave an error: ', timeout : 'Your request timed out' }

Dimmer Message
Dimmer sub-header