ColdBox REST APIs Refcard
ColdBox REST APIs Refcard
www.coldbox.org
Covers up to version 3.8.1
Contents
Defining Resources
Returning Data
Status Codes
Caching 3
Security 3
Custom Security
Error Handling
ColdBox Relax
DEFINING RESOURCES
Resources should usually be nouns as they represent the objects being
accessed or modified by the API. A REST API can define its resources on
its own domain (http://api.example.com), or after a static placeholder
that differentiates it from the rest of the app (http://www.example.com/
api/). We'll use the latter for these examples. Let's consider a resource we
need to represent called "user". It is also important to note that REST is a
style of URL architecture not a mandate, so it is an open avenue of sorts.
However, you must stay true to its concepts of resources and usage of the
HTTP verbs. Here are a few pointers when using the HTTP verbs:
http://www.example.com/api/user
The GETs will return the results in the body of the HTTP response. The
POST and PUT would expect to receive data in the body of the HTTP
request. Whether or not the DELETE returns data (other than its status
code) is up to you.
Note: GET, PUT, and DELETE methods should be idempotent
which means repeated requests to the same URI don't
do anything. Repeated POST calls however, would create
multiple users.
In ColdBox, the easiest way to represent our "/api/user" resource is to
create a handler called "user.cfc" in the /handlers/api/ directory. In this
instance, ColdBox will consider the "api" to be a handler package. Here in
my handler, I have stubbed out actions for each of the operations I need
to perform against my user resource.
/handlers/api/user.cfc
component {
// Save a user
}
// Remove a user
}
}
www.coldbox.org
RETURNING DATA
REST does not dictate the format of data you use to represent your data.
It can be JSON, XML, WDDX, plain text, or something else of your choosing.
The most common way to return data from your handler's action is to use
the event object's renderData() method. It takes complex data and turns
it into a string representation. Here are some of the most common formats
supported by event.renderData():
XML
JSON
TEXT
WDDX
PDF
HTML
Using ColdBoxs data rendering in your REST handlers looks like this:
// xml marshalling
The code above will create default routes based on ColdBoxs conventions.
You can also have full control of what the URL looks like though by mapping
flexible URL patterns and HTTP verbs to the handler and action that will
service each request. To do this, use the /config/routes.cfm file to declare
URL routes we want the application to capture and define how to process
them.
Let's add the following new routes to our /config/routes.cfm file BEFORE the
default route.
pattern = 'api/user',
handler = 'api.user',
action = 'index'
);
// Map route to specific user.
// Different verbs call different actions!
addRoute(
pattern = 'api/user/:userID',
handler = 'api.user',
action = {
GET = 'view',
POST = 'save',
PUT = 'save',
DELETE = 'remove'
});
You can see if that if action is a string, all HTTP verbs will be mapped there,
however a struct can also be provided that maps different verbs to different
actions. This gives you exact control over how the requests are routed.
The :userID part of the route pattern is a placeholder. It matches whatever
text is in the URL in that position. The value of the text that is matched will
be available to you in the request collection as rc.userID. You can get even
more specific about what kind of text you want to match in your route pattern
by specifying patterns that only match numeric/alpha characters, or take full
control with regex patterns.
More on pattern matching can be found in the docs here:
http://wiki.coldbox.org/wiki/Building_Rest_APIs.cfm#Route_Placeholders
}
// json marshalling
function getUsersJSON( event, rc, prc ){
Many APIs allow the user to choose the format they want back from the
endpoint by appending a file "extension" to the end of the URL.
http://www.example.com/api/user.json
http://www.example.com/api/user.xml
http://www.example.com/api/user.text
ColdBox has built-in support for detecting an extension in the URL and will
save it into the request collection in a variable called format. What's even
better is that renderData() can find the the format variable and automatically
render your data in the appropriate way. All you need to do is pass in a list of
valid rendering formats and renderData() will do the rest.
function index( event, rc, prc ) {
event.renderData(data=qUsers, formats="json,xml,text");
}
Of course, if you want more control you can generate the output of your REST
calls to your choosing and simply return a string directly from your handler
that will be the output the client receives.
function index( event, rc, prc ) {
}
www.coldbox.org
STATUS CODES
/config/ColdBox.cfc
Status codes are a core concept in HTTP and REST APIs use them to send
messages back to the client. Here are a few sample REST status codes
and messages.
202 Created - The resource was created successfully
400 Bad Request - The server couldn't figure out what the client was
200 OK - Everything is hunky-dory
sending it
if ( qUser.recordCount ) {
event.getHTTPContent() );
event.renderData( type="JSON",
}
Status codes can also be set manually by using the event.setHTTPHeader()
method in your handler.
function worldPeace( event, rc, prc ){
event.setHTTPHeader( statusCode=501,
Next, simply add the cache=true annotation to any action you want
to be cached. That's it! You can also get fancy, and specify an optional
cacheTimeout and cacheLastAccesstimeout (in minutes) to control how long
to cache the data.
// Cache for default timeout
function showEntry( event, rc, prc ) cache="true" {
prc.qEntry = getData();
prc.qEntry = getData();
SECURITY
coldbox.eventCaching = true;
statusText="Not Implemented" );
if ( !securityService.authenticate( auth.username,
auth.password ) ) {
event.renderData(
type="JSON",
data={
},
statusCode=401,
CACHING
One of the great benefits of building your REST API on the ColdBox platform
is tapping into great features such as event caching. Event caching allows you
to cache the entire response for a resource using the incoming FORM and
URL variables as the cache key. To enable event caching, set the following flag
to true in your ColdBox config.
to do that");
}
}
CUSTOM SECURITY
You can also implement more customized solutions by tapping into any of the
ColdBox interception points such as preProcess which is announced at the
start of every request. Remember interceptors can include an eventPattern
annotation to limit what ColdBox events they apply to. Below, our example
interceptor will only fire if the ColdBox event starts with api..
In addition to having access to the entire request collection, the event object
also has handy methods such as event.getHTTPHeader() to pull specific
headers from the HTTP request.
This example will see if an HTTP header called APIUser is equal to the value
Honest Abe. If not, it will return the results of an error event.
/interceptors/APISecurity.cfc
/**
* This interceptor secures all API requests
*/
component {
// This will only run when the event starts with "api."
eventPattern = '^api\.' {
event.overrideEvent('api.general.authFailed');
}
www.coldbox.org
The keys in the allowedMethods struct are the names of the actions and the
values are a list of allowed HTTP methods. If the action is not listed in the
structure, then it means allow all. Illegal calls will throw a 405 exception. You
can catch this scenario and still return a properly-formatted response to your
clients by using the onError() convention in your handler or an exception
handler which applies to the entire app.
ERROR HANDLING
ColdBox REST APIs can use all the same error faculties that an ordinary
ColdBox application has. We'll cover two of the most common ways here.
Handler onError()
If you create a method called onError() in a handler, ColdBox will
automatically call that method for runtime errors that occur while executing
any of the actions in that handler. This allows for localized error handling that
is customized to that resource.
// error uniformity for resources
function onError( event, rc, prc, faultaction, exception ) {
#event.getCurrentRoutedURL()#');
// log exception
event.renderData(
data={
status = 'error',
detail = thisMessage
},
type = 'json',
statusCode = '500',
statusMessage = thisMessage );
interceptors = [
{class='coldbox.system.interceptors.SES'},
The global exception handler will get called for any runtime errors that
happen anywhere in the typical flow of your application. This is like the
onError() convention but covers the entire application. First, configure the
event you want called in the ColdBox.cfc config file. The event must have the
handler plus action that you want called.
{class='interceptors.APISecurity'}
];
this.allowedMethods = {
remove = 'POST,DELETE',
list
= 'GET'
};
/config/ColdBox.cfc
coldbox = {
...
exceptionHandler = 'main.onException'
...
}
www.coldbox.org
Then create that action and put your exception handling code inside. You
can choose to do error logging, notifications, or custom output here. You can
even run other events.
/handlers/main.cfc
component {
subscriber located at
http://groups.google.com/group/coldbox
You can read more about ColdBox error handling in our docs here:
http://wiki.coldbox.org/wiki/ExceptionHandling.cfm
COLDBOX RELAX
https://github.com/ColdBox/coldbox-platform
It's Community
It's Educational
Discounted Rate
Renewal Price
Architectural Reviews
Plans so that you can choose the one that best suit your
Hour Rollover
needs. Subscribe to your plan now and join the Ortus Family!
Custom Development
With all of our plans you will profit not only from discounted
Priority Training
Registration
Standard
Premium
Enterprise
$5699
$14099
$24599
10
30
80
150
20 tickets
60 tickets
160 tickets
300 tickets
$185/hr
$180/hr
$175/hr
$170/hr
$160/hr
$199/month
$1800/year
$5250/year
$13600/year
$2400/year
1-5 B.D.
1-3 B.D.
1-2 B.D.
< 24 hr
< 12 hr
0%
5%
10%
15%
20%
Phone/Online
Appointments
Support Program
Entry
$2099
4 tickets
Support Hours
M1
$199
www.coldbox.org | www.ortussolutions.com
Copyright 2013 Ortus Solutions Corp.
All Rights Reserved
First Edition - April 2014