Framework to create API

In our time, creating online service, you need to think about developing mobile and desktop applications for him, I do not need to explain why. You also need to it wasn't just "vacuum" the app, but would it work with the data that are on the server. And because the application is not on the server side and has no direct access to it, would be nice to them for creating relationships between themselves and the "share photos". The relationship you can build with the API.

In the beginning


As for the relationship needs at least two parties, in our case it will be:
the
    the
  • Service
  • the
  • Application


We will focus on the minimum API which was created to service the activity of which is associated with books. As the framework will be used APIFramework.

Framework. Minimal data.


Code framework written in PHP. Has MVC-like structure of the work. Start of activities of the framework lies in the controllers, which turn rabotaut models and types. As for the mobile app, type in a form as we know it — does not fit in the framework, it is implemented in the class that "could give you" a JSON, XML or plain text.
The framework has a minimal set of capabilities: to access the database, store the logs, load configuration files and to work with auditors.

Residence

The framework should reside on the server and implements the interface script should know this location in order to activate only one file.

Communication

The exchange of messages between the application and API based on GET requests, it is also possible to pass data with a POST.

Each request should consist of two parts:
the
    the
  • of the Object reference (controller)
  • the
  • Action (called controller method)


In practice, this has the form:
the
http://api.<server>/controller.action

The query will run the controller (to the left of the point) and specific action (from the right of the point). These two parameters must be separated by point and not allowed empty values, if it happens (will be passed an empty value) — the code will be forwarded to the controller error handling. In any case, the result is returned in the format of "who ordered" whether it's JSON or XML.

Example of the minimum XML-formatted response:
the
<?xml version="1.0" encoding="UTF-8">
<status>success</status>


API. Run.


The implementation of the interface originates in the creation of a class of the interface. This class must inherit the class APIFramework that implements the methods to start the entire process. Three such methods.

I want to remind you:
will focus on minimum API which was created to service, whose activities are related to books.

1. method. Initialization

Because the database is the vital part, will start with her. The framework supports the creation of multiple connections to different servers, you need only ask their names as in the following example, the connection name is local.
the
new Connection("local", "localhost", "root", "root", "library");

Interesting creates a connection to nowhere, right? In fact, the framework is there, the connection Manager (performed as solo), and the Connection class is just the messenger that tells the Manager about the new connections.

The next step is to plug connection. The framework does not put specific requirements for plugins. This can be a class, a function or something in PHP. Download (means a simple include) plugins are made using a class of Plugins that works according to the scheme described above.
the
new Plugins(array("User", "Session"));
new Plugins("Language");

It is important to note that the constructor takes as a single string and an array of strings to connect multiple plugins at once.
The last point that I want to mention is the formation of the list of available controllers.
the
new AvailableControllers(array("error", "books"));

It's not unimportant part of the initialization, it is on this list will be checked for the presence of the controller, which will be called from the query string:
http://api.<server>/controller.action

Considering our example with books, we will need at least two controllers — one directly for queries regarding books and the other for error handling, which anyway must be present.

No less important parameter is the outputType. it defines in what format the result is returned. In order to set (default is JSON) the format of the returned values need to execute the function:
the
$this- > setOutputType("XML");

This basic initialization is complete. However, in the body initialization may also be present a code developer who is required to work, for example to create a user class or something.

the Complete code for the initialization function

public function initialize() {

new Connection("local", "localhost", "root", "root", "library");

new Plugins(array("Users"));

new AvailableControllers(array("error", "books"));

$this- > setOutputType("JSON");

$user_id = Session::getUser();
if($user_id > 0) $this->user = new User($user_id); 
}


2nd method. Run

In this method we check for the existence of controller for starting, in case if the name of the controller specified is incorrect or it does not exist, we redirect code to the controller to handle errors.
the

if(!$this->isValidateController()) {

Registry::set("unknow_controller_name", $this->getController());

$this->redirect("error.unknow_controller");
}


The method getController is a member of the parent class and returns the name of the current controller.
Redirect — used to redirect or simple words to replace the name of the controller and its events.

Also in this method, you can check to authorize user or deny access to certain controllers if the user is not authorized.

Full code to the start function

public function execute() {

if(!$this->isValidateController()) {

$this->redirect("error.unknow_controller");
}

if(!$this->user) {

if($this->getController() == "account") $this->redirect("error.unauthorized_user"); 
}
}


After executing the start function, the core of the framework will have two he needs parameters: controller and action. Their presence is enough to continue. The next step will be the launch controller, which will be discussed below.

the 3rd method. Shutdown

This method allows to perform actions after launching and controller but before sending the results. In our case with books, there is nothing special that you need to perform this method.

the
public function finalize() {
}


API. Controller.


The controller is a kind of box with a specific set of tools (actions). Each controller must extend the Controller class, which provides access to external data (parameters passed via GET or POST requests):
the
$book_id = $this->get("book_id");

Also not a few important part of the controller is the connection models:
the
new UseModel("Books");

And finally, the "get" events or actions. Means a function with the same name as the action name in the request line coming from the point. An example of this operation, in our case, bude get a list of available books on the query side it will look like:
the
http://api.<server>/books.get_available

Accordingly, we must beat a controller named Books and the action function.
the
public function get_available() { }

Following the function name, it should return a list of available books. For this you will use the model and the view (as mentioned above, under the guise refers to the class that returns the result as JSON or XML.
The model we have connected with UseModel. You only have to fill the form, procedure of filling simple — and you can see it in the full code of the action.

Full code of the action get_available

public function get_available() {

// Our model
$books = new Books();

// Array of books provided by the model
$items = $books->getAvailable();

// Our view
$view = new View();

$view->add("available_books", $items);

$this->out($view);
}

In the end, when the new — need to send "exit" on the function of the controller out in which to transmit.

In the controller the number of functions / actions must be equal to their sheer quantity. That is, if the object (controller) performs only one action — the number of functions must be equal to 1, if such action 2 — accordingly we need to create two functions with the names of these actions.

controller code
class BooksController extends Controller {

public function initialize() {

new UseModel("Books");
}

public function get_available() {

$books = new Books();

$items = $books->getAvailable();

$view = new View();
$view->add("available_books", $items);
$this->out($view);
}
}

As a result of submitting to the controller at the following address:
the
http://api.<server>/books.get_available

Is the following JSON:
the
{"available_books":[
{"id":1,"title":"Book's title","pages_count":374},
{"id":2,"title":"the Book's title 2","pages_count":965},
{"id":3,"title":"Book's title 3","pages_count":145}
]}


API. Model.


The model provides an object that knows where and what data are, and also how to work with them.

If we consider the model that was used above for a list of available books it turns out the next thing. There is a class named Books (it inherits from the class Model), which has a method getAvailable, which returns an array of available books.

To get a list of books we will need a simple access database. This will create an object of type Query, which makes this possible.
the
$q = new Query("SELECT * FROM `books`");


The next step was to "transition" lines, which are obtained from the database, this object has a method isNext which will return truth (true) until then, until "end of line".
the
$items = array();

while($q- > isNext()) {

$items [] = array(

"id" => $q["id"],
"title" => $q["title"],
"pages_count" => $q["pages_count"]
);
}

As a result, this method will return the "accumulated" array of books.

model code
class Books extends Model {

public function getAvailable() {

$q = new Query("SELECT * FROM `books`");

$items = array();

while($q- > isNext()) {

$items [] = array(

"id" => $q["id"],
"title" => $q["title"],
"pages_count" => $q["pages_count"]
);
}

return $items;
}
}

API. View.


Perhaps the easiest of the above, because he needs only one method, add:
the
$view->add("status", "success");
$view->add("available_books", $items);

API. Structure.


The directory tree created by the above API is the following:
Hidden text
boooks-app
- app
- configuration
- main.cfg
- controllers 
- books 
books.controller.php
- error
error.controoler.php
- models
- books
books.model.php
- plugins
- users
users.plugin.php
users.class.php
book.api.php
- cache
- configuration
- logs
- htdocs
.htaccess
index.php

For correct work of the framework will require htaccess and its capabilities.
.htaccess
RewriteEngine On

RewriteCond %{REQUEST_URI} !/index.php
RewriteCond %{REQUEST_URI} !/favicon.ico

RewriteRule ^(.*) index.php?__api_framework_request_string=$1&%{QUERY_STRING} [L]

Options-Indexes

File index.php has the following form:
index.php

error_reporting(0);

define("APPLICATION_NAME", "Books", true);

define("API_FRAMEWORK_PATH", "<framework path>/", true);
define("APPLICATION_PATH", "<application path>/", true);

require_once API_FRAMEWORK_PATH . "framework.php";
require_once APPLICATION_PATH . "/ app/" . APPLICATION_NAME . ".API.php";

$application_name = strval(APPLICATION_NAME) . "API";

$application = new $application_name();


Opinion


0. Thank you for taking the time to read.
1. I hope the material was useful.
3. The framework developed by their own hands.
4. api-framework

Thank you.
Article based on information from habrahabr.ru

Комментарии

Популярные сообщения из этого блога

Why I left Google Zurich

2000 3000 icons ready — become a sponsor! (the table of orders)

New web-interface for statistics and listen to the calls for IP PBX Asterisk