Hi there,
I am not sure if can explain well, but i will try.
I have started to work on something similar to Google Api’s explorer (https://developers.google.com/apis-explorer/#p/) for Yii2.
Basically, I want to be able to develop set of API’s organised into services and have interfece to:
-
list all services
-
list all service methods
-
be able to execute method and display results using Xml, Json etc.
For example i would like to define service as in following sample:
<?php
// Define Sample Service
class UserService
{
public function getServiceInfo()
{
return [
'title' => "User Service",
'description' => 'Provides api to manage users'
];
}
public function getUserByUsernameOrEmail($userNameOrEmail)
{
return User::find()->where("Username = <img src='http://www.yiiframework.com/forum/public/style_emoticons/default/tongue.gif' class='bbc_emoticon' alt=':P' /> OR Email = <img src='http://www.yiiframework.com/forum/public/style_emoticons/default/tongue.gif' class='bbc_emoticon' alt=':P' />", ['<img src='http://www.yiiframework.com/forum/public/style_emoticons/default/tongue.gif' class='bbc_emoticon' alt=':P' />' => $userNameOrEmail])->one();
}
public function getUserById($id)
{
return User::findOne($id);
}
public function getSampleData(MyDataObject $data)
{
return $data;
}
}
// Implement Service wrapper to provide additinal funcionality such as caching,
// logging or performance monitoring
class ServiceWrapper
{
public $clientClass = "";
public $service = "";
public $endPoint = "http://my-url-api/%s?method=%s&args=%s";
private $client = null;
public function getClient()
{
if ($this->client == null) {
$this->client = new $this->clientClass;
}
return $this->client;
}
public function __call($name, $args)
{
$url = sprintf($this->endPoint, $this->service, $name, json_encode($args));
$key = "{$this->clientClass}::$name";
Yii::beginProfile($key, "Rest Service ($url)");
$data = Yii::$app->cache->get($url);
if ($data === false)
{
$data = file_get_contents($url);
Yii::$app->cache->add($url, $data, 15);
}
Yii::endProfile($key);
$result = unserialize($data);
return $result;
}
}
//And finaly configure all together using following
class Service
{
private static $di = null;
private static function getContainer()
{
if (self::$di == null) {
self::setupContainer();
}
return self::$di;
}
private static function setupContainer()
{
$di = new Container();
$di->set('user', [
'class' => 'app\services\ServiceWrapper',
'clientClass' => 'app\services\UserService'
]);
self::$di = $di;
}
public static function setupDirectAccess()
{
$di = new Container();
$di->set('user', [
'class' => 'app\services\UserService',
]);
self::$di = $di;
}
/**
* Returns User Service
* @return \app\services\UserService
*/
public static function user()
{
return self::getContainer()->get("user");
}
}
?>
I belive one of the benefits would be:
-
Be able to directly use service eg. using Service::user()->getUserById(1)
-
Provide REST Api for services, using various serializers such as XML, Json, Bson, PHP Serialization
-
Implement service wrapper, as in sample above to provide accesing services over HTTP or TCP, avoiding direct access to dabase
-
Easier performance monitoring, caching etc.
-
Unify access for multiple applications (Web, iOS, Android)
So far i have implemented sample services and UI for browsing services and methods using reflection, generating form for executing methods and serializers are not yet implemented.
I am wondering if there are similar projects like this, or if there is anyone that would like to work on this.
Thanks,
Edin