languages, an API specifies a set of functions or routines that accomplish a specific task or are allowed to interact with a specific software component. Allows developers to write code interfaces with functionality from another platform
developer you’ve interacted with an API All of the companies on this slide have been successful because they have great apis that other developers wanted to use.
backwards compatible • Graceful when handling errors Saturday, November 9, 13 Understandable & consistent naming is very important in your api, if its hard to use then no matter your features developers wont use it Security is important, you want to make sure only valid allowed programs have access and user data is protected Versioning is also critical, you have to plan for new features without breaking older devs who have built their software on older code Be graceful in handling errors, send back clear and understandable error codes to help the developer using your api diagnose problems
about a recent project of mine who needed an api to an ee addon. They're an elite team of soliders who were wrongly accused of a crime they didnt commit, now they work as soliders of fortune. If you have a problem, if no one else can help, and if you can find them...
developed a module to allow the A-Team to track their missions Now they need a mobile application to integrate with the module, they have a mobile dev lined up, but they need an API exposed to display their missions in JSON.
i decided to rely on the power of ees templating engine by using it to create a simple json feed. Creating a simple JSON feed in EE can be done using EE’s templating methods. A good way to start is to create a new template group. In this case we’ll use “api” then the number 1 to denote the version. This will help us maintain backwards compatibility in the future
template to denote the resource we want to return back, in this case a list of missions. We name the template with a .json extension so EE will return the content as application/json instead of plain-text
13 JSON is simply name-value pairs enclosed by curly brackets. Since we have multiple missions, we have square blocks representing an array of multiple objects We use our addon tag pair (the same tagpair we developed previously) to insert the values for the json name-value pair
conditional “last_item” so we know when to add a separating comma between the missions. On the last item we want to avoid adding a comma as it would not validate as proper JSON
to api1/missions.json, we get a nice output in JSON of our missions. We can also use URL segments to pass parameters to get individual missions, or filter by status/ city, etc This same technique can be used for any ee tag, which makes it pretty handy.
Output JSON • Maps to Module methods Saturday, November 9, 13 Actions are a way for ExpressionEngine to run code in EE core & third-party addons. Which is great because that means we can use them to access the methods in Mission Tracker They support both GET & POST requests & we can control the output to render JSON or XML.
problem with ACTions, can you tell me what API methods these actions map to? If any? That’s right, ACTions are not what I’d call clear and understandable which unfortunately rules them out for our API. Also the action ID changes per environment, which makes it hard to distribute to the users of your API What we need is an easy to understand URI structure that is accessible and maps to our API methods
attaches to the sessions_start ExpressionEngine hook. We then have a conditional that checks to see if segment_1 matches our API trigger, which in this case is simple “api”. If there isn’t a match then the extension ignores the request and passes it on, but if there is a match we attempt to call the API method in segment_2
What about more complex urls? /api/mission/show_all /api/equipment/create • Need support for multiple API classes, better separation of business logic Saturday, November 9, 13 I love this technique but there are some room for improvement. First all of our API methods are in one class, which could be problematic if your API has a lot of features, 20 methods crammed in one class file will get very hard to maintain very quickly Also it doesn’t support a REST-style resource base URLs. I’d prefer to design the API using a “trigger/resource/method” type format. This will help developers using the API understand clearly what models they’re working with Finally splitting up methods into multiple API library classes will help me separate business logic which is a good practice for maintainability.
API classes implement call_method, route_url() will work Saturday, November 9, 13 So how do be modify this technique to support multiple library classes? Well a clue is that the extension method “route_url()” only needs to know to execute “call_method” it doesn’t care about what other methods in the library it’s executing.
13 This means that we can wrap “call_method” into a interface. An interface acts a rule, it basically says “in order to be a valid API class, you must implement a method called “call_method” that accepts one parameter. Notice the interface doesn’t specify how the class should implement call_method. We want the our extension method to have little to no knowledge of the api class beyond call_method. This is what’s called loose coupling & it’s a important concept when designing flexible code.
13 Now in our extension in the route_url method, we modify it so that segment_2 maps to our resource, in this case it’s Mission. We use ee()->load->library to look for a class “Mission_lib” and load it into EE
a third parameter to load->library called “mission_api” as a pointer or bookmark to our Mission_lib api class. Finally we use the third URL segment for our API method, in this case “show_all”
9, 13 If we wanted to extend our API to include Equipment, the extension will load the Equipment_lib class without us having to modify any addition code. Of course this could be pretty dangerous, as it does leave open the possibility of executing any arbitrary code, not just our API methods. That’s why I wrap this code in a conditional that checks the second segment url first to make sure its approved
from Ben’s Open API module. The main work is done by php’s json_encode function. PHP also can decode JSON using json_decode, so it’s really easy to work with JSON in PHP and I prefer it over XML
our insert method in the model, we call then use EE’s built in db class methods to safely create the new mission Finally we can get back the newly created unique id for the mission by using insert_id
for registered apps, send via POST • Encrypt using SSL (https://) • Use ee()-input & ee()- db Saturday, November 9, 13 You can go deeper to secure your API, but at the very least create randomly generated API keys for registered apps. Force the apps to send the get in POST requests (you want to avoid using URLs as the key can be written to server logs). Reject requests that don’t have the proper key Use SSL, or HTTPS. It won’t avoid man in the middle attacks, but it makes them harder Use EE’s input & db libraries instead of raw PHP code to process forms. Be paranoid about any input you get from your API and be extremely narrow what data you’ll accept
into libraries for reusability • Use Versioning for backward compatibility • Keep URIs consistent & understandable Best Practices Saturday, November 9, 13 Use CodeIgniter Model to DRY (Don’t Repeat Yourself) the idea should be your API will use the same business logic as the rest of your module Organize your code into libraries for reusability, move common code for your api into base classes. Version your code for backward compatibility, you can use version numbers in the url which means you’ll have to modify your extension slightly. Or use parameters to specify version numbers. Either way ensure updates don’t break the developers on previous versions Your API & the URIs used to access the code should be consistent & understandable
• Fiddler - http://fiddler2.com/ Saturday, November 9, 13 JSONLint.com to validate/test JSON is valid Postman is a REST client for Chrome, send & receive HTTP request & responses, very good tool for quick inspection of your API without having to right an app. Although I’d highly recommend learning PHPUnit or SimpleTest and writing real unit tests. Finally if you’re on windows there’s Fiddler which is an amazing powerful tool for debugging HTTP requests & responses. It’s an amazing Pro tool and can also execute man-in the middle attacks to test your security. Windows is best but there’s an alpha for Mac/Linux based systems.