From a048660f2d2e41111a56eaba4c594474eb3815e1 Mon Sep 17 00:00:00 2001 From: jlukic Date: Thu, 9 Oct 2014 14:12:42 -0400 Subject: [PATCH] Updates to API docs --- server/documents/modules/api.html.eco | 403 +++++++++++--------------- server/files/javascript/api.js | 13 +- 2 files changed, 188 insertions(+), 228 deletions(-) diff --git a/server/documents/modules/api.html.eco b/server/documents/modules/api.html.eco index 304f8fb6b..9f8bdae3a 100644 --- a/server/documents/modules/api.html.eco +++ b/server/documents/modules/api.html.eco @@ -4,7 +4,7 @@ css : 'api' title : 'API' description : 'API allows UI elements to send events to the server' -type : 'Draft' +type : 'UI Behavior' --- @@ -30,8 +30,7 @@ type : 'Draft'
Deal with resources not URLs
-

Store all your API endpoints as templated URLs in one place inside your code, and then trigger named human readable API actions like 'get tweet'.

-
See example
+

Create named actions like 'follow user' and have API handle URL templating, parameters, and other annoyances for you.

@@ -45,265 +44,217 @@ type : 'Draft'
Server Traces For Humans
-

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

+

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

-
+
-
-

Demo

-
-
-
- -
-
-
- - Adopt -
+
+
+
+ +
+
+ Stevie Feliciano +
+ Joined in Sep 2014
+
-

1. Define Your API

-

API works best when using a named list of endpoints. This means you can maintain all of your website's API endpoints in a single location, without having to update them across the site.

-

To do this you must include a list of named endpoints before calling $.api on any page. The easiest way to do this is to have it available in a stand-alone configuration file.

- -

For the sake of this example we will use Github's public API as an example

-
- /* "Config.js" - Define API endpoints once globally */ - $.fn.api.settings.api = { - 'follow user' : '/api/follow/{$id}', - 'user info' : '/api/user/{$id}' - }; -
-
- - +

Creating an API

+ +
+

Define Your API

+

API works best by defining named API actions which can be converted to URLs for each request/

+

To do this you must define your endpoints once in your application before making requests. Usually this is done in a central configuration file included on each page.

+

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

+

Required Parameters will abort the request if they cannot be replaced when triggered.

+

Optional Parameters will be removed from the url if are not included when triggered. In addition, any trailing slashes before an optional parameter will also be removed from the URL, allowing you to include them in resource paths.

+
+ $.fn.api.settings.api = { + 'endpoint': 'api/{required}/{/optional}/{/optional2}' + }; +
+ +
+ /* Define API endpoints once globally */ + $.fn.api.settings.api = { + 'get user' : '/user/{id}', + 'get followers' : '/followers/{id}?results={count}', + 'follow user' : '/follow/{id}', + 'add user' : '/add/{id}', + }; +
-

2. Attach an API event to an element

+

Calling API Actions

+ +
+

Automatic Events

-

Any element can have an API action attached, by default the action will occur on the most relevant event for the type of element. For example a button will use on click or an input oninputchange

+

Any element can have an API action attached, by default the action will occur on the most relevant event for the type of element. For example a button will use onclick or an input oninput.

+ +
+ AJAX requests for the following demos have been faked using SinonJS to avoid rate throttling from public APIs. +
-
- $('.adopt.button') - .api({ - action: 'follow user' - }) - ; +
+ $('.follow.button') + .api({ + action: 'follow user' + }) + ; +
-

2. Specify state changes to text or appearance (optional)

-

API couples well with ui state, a component used for managing text state and class names of elements.

-

State will automatically apply the class active on API success, and update any text nodes with new values specified. This example updates the text of a follow button to "following" when the API action is successful, after flashing the text success.

-
- $('.adopt.button') - .state({ - text: { - inactive : 'Adopt', - active : 'Adopted', - deactivate : 'Undo', - flash : 'Success' - } - }) - ; +
+

Manual Events

+

If you need to manually override what action an API event occurs on you can use the on parameter. In addition, using the special parameter on: 'now' will trigger the api event immediately.

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

Calling Immediately

+

If you need to manually override what action an API event occurs on you can use the on parameter. In addition, using the special parameter on: 'now' will trigger the api event immediately.

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

4. Make sure metadata is set for an element before event occurs

+

Setting Conditions

-

When an API action occurs, templated url data is replaced with data you specify to be sent to the server.

-
-
+
+

URL Variables For API Request

+

Templated variables set in your API are replaced during your request in three different ways.

+ +
...by Data Attributes
+

If many elements trigger a similar function, it is often easiest to include data attribute for each instance with the specific url variables

+
+ + +
+
....in Javascript
+

URL variables can be specified at run-time in the javascript object

+
+ $('.follow.button') + .api({ + action: 'follow user', + urlData: { + id: 22 + } + }) + ; +
+
...returned values from beforeSend Callback
+

In addition all parameters can be adjusted in a special callback beforeSend which occurs, quite intuitively, before the API request is sent.

+

You can also use this callback to adjust other settings before each API call

+
+ $('.follow.button') + .api({ + action: 'follow user', + beforeSend: function(settings) { + settings.urlData = { + id: 22 + }; + return settings; + } + }) + ; +
-
Or
-

Alternatively you can modify the data before sending to server

-
- $('.adopt.button') - .api('setting', 'beforeSend', function(settings) { - settings.urlData.id = 5209; - return settings; - }) - ; + +
+

3. Defining UI State

+ +

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

+ +
Learn more about states
+ +

API will automatically attach a Loading state when an API request is triggered, additional states can be attached using state behaviors, an optional component that couples well with API behaviors.

+ +

If state is initialized, it will automatically apply the class active on API success, and update any text nodes with new values specified.

+ +

State also includes other states:

+
    +
  • Inactive - Default state
  • +
  • Active - API request is completed succesfully
  • +
  • Enable - Text on hover if currently in inactive state
  • +
  • Deactivate - Text on hover if currently in active state
  • +
  • Hover - Text appears on hover regardless of state
  • +
  • Flash - Text appears on element for time duration set by flashDuration +
+ +
+ $('.follow.button') + .state({ + text: { + inactive : 'Adopt', + active : 'Adopted', + deactivate : 'Undo', + flash : 'Success' + } + }) + ; +
+
+ +
+

4. Make sure metadata is set for an element before event occurs

+ +

When an API action occurs, templated url data is replaced with data you specify to be sent to the server.

+
+
+
+
Or
+

Alternatively you can modify the data before sending to server

+
+ $('.adopt.button') + .api('setting', 'beforeSend', function(settings) { + settings.urlData.id = 5209; + return settings; + }) + ; +
+ + + + + + + -
-

Overlay

-

A api can overlay page content instead of pushing it to the side

-
- $('.overlay.api') - .api({ - overlay: true - }) - .api('toggle') - ; -
-
-

- API Settings -
Form settings modify the api behavior
-

- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SettingDefaultDescription
overlayfalseWhether api should overlay page instead of pushing page to the side
exclusivetrueWhether multiple apis can be open at once
useCSStrueWhether to use css animations or fallback javascript animations
duration300Duration of side bar transition animation
- -
-

Callbacks

-

Callbacks specify a function to occur after a specific behavior.

- - - - - - - - - - - - - - - - - - - - - - - - -
SettingContextDescription
onShowAPIIs called when a api is shown.
onHideAPIIs called when a api is hidden.
onChangeAPIIs called after a api changes visibility
- -
- -

- DOM Settings -
DOM settings specify how this module should interface with the DOM
-

- - - - - - - - - - - - - - - - - - -
SettingDefaultDescription
namespaceapiEvent namespace. Makes sure module teardown does not effect other events attached to an element.
className -
- className: { - active : 'active', - pushed : 'pushed', - top : 'top', - left : 'left', - right : 'right', - bottom : 'bottom' - } -
-
Class names used to attach style to state
- -
- -

- Debug Settings -
Debug settings controls debug output to the console
-

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SettingDefaultDescription
nameAPIName used in debug logs
debugTrueProvides standard debug output to console
performanceTrueProvides standard debug output to console
verboseTrueProvides ancillary debug output to console
errors -
- error : { - method : 'The method you called is not defined.', - notFound : 'There were no elements that matched the specified selector' - } -
-
diff --git a/server/files/javascript/api.js b/server/files/javascript/api.js index c9e291090..77241fb28 100755 --- a/server/files/javascript/api.js +++ b/server/files/javascript/api.js @@ -1,5 +1,14 @@ -semantic.api = {}; +/* Define API endpoints once globally */ +$.fn.api.settings.debug = true; +$.fn.api.settings.api = { + 'get user' : '/user/{id}', + 'get followers' : '/followers/{id}?results={count}', + 'follow user' : '/follow/{id}', + 'add user' : '/add/{id}', +}; + +semantic.api = {}; // ready event semantic.api.ready = function() { @@ -17,7 +26,7 @@ semantic.api.ready = function() { server.autoRespondAfter = 500; server - .respondWith(method, '/api/follow/5209', [responseCode, headers, body]) + .respondWith(/\/follow\/(\d+)/, [responseCode, headers, body]) ; };