Matthew Clemente
REpresentational State Transfer
HyperText Transfer Protocol
Adam Tuttle, REST Assured: A Pragmatic Approach to API Design, 2019
hyper
A CFML HTTP Builder
box install hyperapi-wrapper-template
A CommandBox tool for scaffolding CFML API Clients
box install api-wrapper-templateapiWrapper scaffold --wizard
| apiName* | Name of the API this library will wrap, i.e. Stripe |
| apiEndpointUrl* | Base endpoint URL for API calls, i.e. https://api.stripe.com/v1 |
| apiAuthentication | Type of authentication used [None, Basic, Apikey, Other] |
| apiDocUrl | URL of the API documentation homepage |
| name | Name for the wrapper [i.e. StripeCFC] |
| description | A short description of the wrapper. |
| author | Name of the author of the wrapper. |
| package | Create a box.json - for use as a Forgebox package (yes/no) |
apiwrapper scaffold
apiName = "The Cat API"
apiEndpointUrl = "https://api.thecatapi.com/v1"
apiAuthentication = "apikey"
apiDocUrl = "https://docs.thecatapi.com/"
name = "CFCat"
description = "Some people are dog people. Others are
cat people. This wrapper will provide
the latter with cats on demand."
package = "true"
Make sure there's a method to your madness
| CRUD | HTTP Verb | Method |
|---|---|---|
| Create | POST |
createItem(data) |
| Read | GET |
getItem(id) listItems() |
| Update | PUT/PATCH |
updateItem(id) |
| Delete | DELETE |
deleteItem(id) |
catapi = new cfcat.catapi();
catGif = catapi.getRandomGif().data;
writeOutput( '<img src="#catGif.url#">' );RequestBin / Hookbin / Mockbin
catapi = new cfcat.catapi( includeRaw = true );
data = {
"size": "full",
"breed_id": "raga",
"limit": 1
};
writeDump( catapi.search( data ) );Authentication typically involves providing credentials via Headers
| No Authentication | This is easy! You don't need to do anything! |
| Basic Authentication | Base64 encoded username:password in Authorization header |
| API Key Authentication | Unique identifiers passed via headers (less frequently, via query params or the body) |
| Open Authorization (OAuth) | Access Token used, following authentication and permission |
How do we handle it in our CFML API clients?
| No Authentication | This is easy! You don't need to do anything! |
| Basic Authentication | cfhttp username and password attributes |
| API Key Authentication |
cfhttpparam( type="header", name="api-key", value=value ); |
| Open Authorization (OAuth) | https://github.com/coldfumonkeh/oauth2 |
Keeping credentials in environment variables
provides practical and security benefits
// Get access to the system class.
system = createObject( "java", "java.lang.System" );
// Get a specific environment variable
value1 = system.getenv( 'key' );
// Get a specific system property
value2 = system.getProperty( 'key' )
// Get a struct of env vars or system props
environment = system.getenv();
properties = system.getProperties();
Handled automatically in api-wrapper-template
apiwrapper scaffold
apiName = "Aylien"
apiEndpointUrl = "https://api.aylien.com/api/v1"
apiAuthentication = "apikey"
apiDocUrl = "http://docs.aylien.com/textapi/"
name = "ayliencfc"
description = "Access Aylien's Natural Language
Processing (NLP) API to extract meaning
and insight from textual content."
package = "true"
aylien = new aylien.aylien();
entities = aylien.entities( url = 'http://bit.ly/cfsummit2019' ).data;
writeDump( entities );aylien = new aylien.aylien();
entities = aylien.entities( url = 'http://bit.ly/cfsummit2019' );
writeDump( entities );aylien = new aylien.aylien();
entities = aylien.entities( url = 'I am not a URL!' );
writeDump( entities );entities = aylien.entities( 'http://bit.ly/cfsummit2019' ).data;apiwrapper scaffold
apiName = "Lob"
apiEndpointUrl = "https://api.lob.com/v1"
apiAuthentication = "basic"
apiDocUrl = "https://lob.com/docs"
name = "lobcfc"
description = "Wrap the Lob API to verify
addresses and send physical
mail programmatically."
package = "true"
lob = new lob.lob( forceTestMode = true );
//etc etc
result = lob.createPostcard( postcard );Pass all parameters as a struct
Helper components with fluent interfaces
/helpers/address.cfc
/helpers/address.cfc
(Because don't you prefer well documented repositories)
🧐📖
Matthew Clemente