mdelariva / api-model
API Model
Requires
- php: >=7.0
- ext-json: *
- illuminate/cache: >=6
- illuminate/contracts: >=6
- illuminate/database: >=6
- illuminate/filesystem: >=6
- illuminate/http: >=6
- illuminate/pagination: >=6
- illuminate/support: >=6
- laravel/framework: >=6
README
Basic Laravel API client, Eloquent styled.
Installation
Composer
Require package
composer require mdelariva/api-model
And publish the configuration for Provider: MdelaRiva\ApiModel\Providers\ServiceProvider
php artisan vendor:publish
GIT
Clone repository
git clone git@bitbucket.org:marianodelariva/api-model.git
And publish the configuration for Provider: MdelaRiva\ApiModel\Providers\ServiceProvider
php artisan vendor:publish
Usage
1- Fill the configuration in .env
and/or config/apimodel.php
2- Extend your model from MdelaRiva\ApiModel\ApiModelAbstract
<?php
namespace App\Models;
use MdelaRiva\ApiModel\ApiModelAbstract;
class Article extends ApiModelAbstract
{
}
3- Use your model in your controller like you were using Eloquent
<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use App\Models\Article;
class ArticleController extends Controller
{
public function index()
{
// Find item
$article = Article::find( 1 );
$article = Article::findOrFail( 1 );
// Update item
$article->status = 2;
$article->save();
// Create item
$article = new Article();
$article->status = 2;
$article->save();
// Delete item
$article->delete();
Article::destroy( 1 );
// Full List
$articleList = Article::all();
// Query List
$articleList = Article::where( 'status', 2 )->orderBy( 'status' )->get();
// Single item
$article = Article::where( 'status', 2 )->orderBy( 'status', 'desc' )->first();
// Query object
$articleQuery = Article::query();
$articleList = $articleQuery::where( 'status', 2 )->get();
}
}
Configuration
Options available in config/apimodel.php
Option | .env | Required | Type | Description |
---|---|---|---|---|
default | APIMODEL_CONNECTION | Y | string | Key of the connections option list, to use as default connection. If you use the protected connection property in your model, you will override the connection for that model only. |
connections | - | Y | array | List of connections (single or grouped) available (see list of options below). |
Single connection options
Option | .env | Required | Type | Description |
---|---|---|---|---|
driver | - | Y | string | Translator between remote API and query methods. Default: \MdelaRiva\ApiModel\Drivers\Basic::class . |
connector | - | Y | string | API client connector. Default: \MdelaRiva\ApiModel\Connectors\Connector::class . |
persist_type | - | Y | string | Authentication saving persistent type. Options available: cache , session . Default: cache . |
url | APIMODEL_HOST | Y | string | Remote API base url. Example: https://api.example.com/ . |
version | APIMODEL_VERSION | N | string | Remote API version. If filled, it will be appended to url. Examples: v1.2 , 3.2 , api . |
authorization | - | Y | array | Authorization. See description and options above. |
verify | APIMODEL_VERIFY | N | bool|string | SSL certificate verification behavior of a request. Set to TRUE to enable SSL certificate verification and use the default CA bundle provided by operating system. Set to FALSE to disable certificate verification (this is insecure!). Set to a string to provide the path to a CA bundle to enable verification using a custom certificate. |
allow_redirects | - | N | bool | Describes the redirect behavior of a request. Set to TRUE to enable normal redirects with a maximum number of 5 redirects. Default: FALSE |
debug | - | N | bool | Set to TRUE to enable debug output. Default: FALSE . |
wrappers | - | N | array | Wrappers. List of properties for collection responses. |
wrappers.collection.root | - | N | string | Wrappers. Name of the property that wraps the collection. Default: data . |
wrappers.collection.pagination.total | - | N | string | Wrappers. Name of the property that wraps the amount of total results, inside the pagination information object. Default: meta.total . |
cache | - | N | array | Cache. List of cache properties. |
cache.enabled | - | N | bool | Cache. Global flag to enable/disable cache. Default: null . |
cache.path | - | Y | string | Cache. Cache store path. Default: storage_path( 'framework/cache/data/apimodel/' ) |
cache.ttl | - | N | int | Cache. Time, in seconds, that an object will be stored in a cache. Default: 86400 . |
throttler | - | N | array | Throttler. List of Throttler properties. |
throttler.throw_exception | - | N | bool | Throttler. If too many request are made, return FALSE or throw a ThrottleRequestsException exception. Default: FALSE . |
throttler.limits | - | N | array | Throttler. List of rate limits elements (see list of options below). |
timeout | - | N | int | Connection timeout (in seconds). |
logging | - | N | array | Logging. List of logging properties. |
logging.enabled | - | N | bool | Logging. Flag to enable/disable connection logging. Default: false . |
logging.type | - | N | string | Logging. Logging types. Options available: requests , cache . If empty, logs all types. |
Authorization
Option | .env | Required | Type | Auth type related | Description |
---|---|---|---|---|---|
type | - | Y | string | - | Authorization type. See available options above. |
oauth_endpoint | - | - | string | oauth_2 | Oauth endpoint. Default: oauth/token . |
oauth_base64header | - | - | bool | oauth_2 | Set to TRUE to send the Token in the Authorization header instead of the request body. Default: FALSE . |
401_refresh_token | - | - | bool | oauth_2 | Set to TRUE to automatically refresh the access token when the server returns a 401 error. Default: FALSE . |
credentials | - | - | array | - | List of credentials. |
credentials.client_id | APIMODEL_CLIENT_ID | Y | string | oauth_2 | Client ID. |
credentials.client_secret | APIMODEL_CLIENT_SECRET | Y | string | oauth_2 | Client secret. |
credentials.query | - | Y | array | api_key_query | Array of credentials key => value sent via query. |
credentials.headers | - | Y | array | api_key_header | Array of credentials key => value sent via headers. |
credentials.token | - | Y | string | bearer_token | Bearer Token. |
credentials.username | - | Y | string | basic_auth | Username for login. |
credentials.password | - | Y | string | basic_auth | Password for login. |
Authorization Types
Option | Description |
---|---|
no_auth | No Auth. No parameters sent. The credentials option is not necessary. |
api_key_query | API Key. Parameters sent via query. |
api_key_header | API Key. Parameters sent via headers. |
bearer_token | Bearer Token. Token is sent as Bearer in the Authorization header. |
basic_auth | Basic Auth. Username and password is sent as a Base64 encoded string in the Authorization header. |
oauth_2 | OAuth 2.0. Credentials are sent to config oauth_endpoint endpoint to require a Token, to be use as Bearer in the Authorization header. All the properties that are defined in the credentials option (besides client_id and client_secret ) will be sent in the request body, to allow authorization customization (e.g. grant_type , scope ). |
For more information about authorization types, see Postman documentation.
Throttler limit element
Option | Required | Type | Description |
---|---|---|---|
max_attempts | Y | int | Amount of attemps allowed. |
decay_seconds | Y | int | Amount of seconds the attemps are allowed. |
Logging
Log files are saved in a logs
folder inside the storage directory with the following file name pattern: apimodel-{conection_name}.log
.
Every request logged has the method used, URL, query parameters, and the type of log.
There are 2 types of logs:
requests
: Logs direct API requests made.cache
: Logs cached API requests.
Grouped connections options
You can define a grouped connection that will rotate through a list of single connections. If a model has a grouped connection set, it will use a single conection every instance is created.
Option | Required | Type | Description |
---|---|---|---|
connections | Y | array | List of single connections names. |
Example of configuration:
<?php
return [
'default' => env('APIMODEL_CONNECTION', 'default'),
'connections' => [
'connection_1' => [
'url' => 'https://api.example.com/',
],
'connection_2' => [
'url' => 'https://api.example.com/',
],
'connection_3' => [
'url' => 'https://api.example.com/',
],
'grouped_connection' => [
'connections' => [
'connection_1',
'connection_2',
'connection_3'
]
],
],
];
Query builder driver
This class includes the methods to use as query builder, and define the parameters that will be sent in the request to the API.
As long as you build a driver that extends from MdelaRiva\ApiModel\Drivers\QueryInterface
, feel free to write your own driver.
Basic (default)
API: https://bitbucket.org/marianodelariva/api-controller
Namespace: MdelaRiva\ApiModel\Drivers\Basic
- Methods allowed
Query method | API Parameter sent |
---|---|
where | {fieldName} |
whereIn | {fieldName} |
limit | limit |
orderBy | orderBy orderByDir |
groupBy | groupBy |
- where
This method allows you to use several operators, that will be translated into a code that will be appended to the parameter name, and the remote API should understand.
Operator | Code appended | Note |
---|---|---|
> | _gt | |
>= | _ge | |
< | _lt | |
<= | _le | |
like | _ct | Value must match %(.*)% |
like | _pr | Value must match %(.*) |
like | _ap | Value must match (.*)% |
Example:
Article::where( 'status', '>=', 2 )
->where( 'name', 'like', 'example%' )
->whereIn( 'section', [3,4] )
->orderBy( 'status', 'asc' )
->get();
API call parameters: status_ge=2&name_ap=example§ion[]=3§ion[]=4&orderBy=status&orderByDir=asc
.
Twitter - Tweets Search
API: https://developer.twitter.com/en/docs/tweets/search
Namespace: MdelaRiva\ApiModel\Drivers\Twitter\TweetsSearch
- Methods allowed
Query method | API Parameter sent |
---|---|
where | query={field}:{value} |
limit | maxResults |
maxResults | maxResults |
groupBy | bucket |
bucket | bucket |
tag | tag |
fromDate | fromDate |
toDate | toDate |
next | next |
tag | tag |
- where
This methods builds the query
parameter.
The $operator
parameter is not taking into account, and the $field
parameter is the Twitter operator (Full list). Unlike the Basic driver, the $value
must be string
.
Example:
TweetsSearch::where( 'lang', 'pt' )
->where( 'query', 'Twitter Dev' )
->fromDate( new \DateTime( '2016-04-22' ) )
->groupBy( 'day' )
->limit( 10 )
->get();
API call parameters: query=Twitter Dev lang:pt&fromDate=201604220000&bucket=day&maxResults=10
.
Pre-built drivers
Twitter - Tweets Search
- API Documentation
- Namespace:
MdelaRiva\ApiModel\Drivers\Twitter\TweetsSearch
Youtube Data API - Channel
- API Documentation
- Namespace:
MdelaRiva\ApiModel\Drivers\Youtube\Channel
Youtube Data API - Search
- API Documentation
- Namespace:
MdelaRiva\ApiModel\Drivers\Youtube\Search
Cache
The enabled
key in config/apimodel.php
is a global flag to enable/disable cache. If TRUE
, it will store all GET requests response. If FALSE
, it won't store any response. If null
, it will depend on each request or model configuration.
Driver used: file
Usage
- Query
For storing an specific query (global flag must be TRUE
or null
), and refreshing it:
<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use App\Models\Article;
class ArticleController extends Controller
{
public function index()
{
// Cache using default configuration
$articleQuery = Article::cacheQuery();
$articleList = $articleQuery::where( 'status', 2 )->orderBy( 'status' )->get();
// Query inline
$articleQuery = Article::cacheQuery()->where( 'status', 2 )->orderBy( 'status' )->get();
// Cache using specific TTL (30 seconds)
$articleQuery = Article::cacheQuery( FALSE, 30 );
$articleList = $articleQuery::where( 'status', 2 )->orderBy( 'status' )->get();
// Make request, refreshing cache
$articleQuery = Article::cacheQuery( TRUE );
$articleList = $articleQuery::where( 'status', 2 )->orderBy( 'status' )->get();
}
}
- Flush
Flush by model
<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use App\Models\Article;
class ArticleController extends Controller
{
public function index()
{
// Flush all Article cache
Article::cacheFlush();
}
}
Model
Methods available
This is a list of the methods that execute a call to the connection:
all
call
get
find
findOrFail
first
firstOrNew
pagination
delete
destroy
save
Configurations
- Pagination
Define the amount of items returned when pagination.
<?php
namespace App\Models;
use MdelaRiva\ApiModel\ApiModelAbstract;
class Article extends ApiModelAbstract
{
protected $perPage = 20;
}
- Connection
The protected $connection
property (string
) must match a key in the connection
array in the apimodel configuration file described above.
<?php
namespace App\Models;
use MdelaRiva\ApiModel\ApiModelAbstract;
class Article extends ApiModelAbstract
{
protected $connection = 'twitter';
}
- Endpoint
If your model name can't match the API endpoint, you can define it manually:
<?php
namespace App\Models;
use MdelaRiva\ApiModel\ApiModelAbstract;
class SomeEndpoint extends ApiModelAbstract
{
protected $endpoint = 'endpoint';
}
- Driver
Set the driver manually (this will overwrite the apimodel file configuration):
<?php
namespace App\Models;
use MdelaRiva\ApiModel\ApiModelAbstract;
class SomeEndpoint extends ApiModelAbstract
{
protected $driver = \MdelaRiva\ApiModel\Drivers\Youtube\Channel::class;
}
- Custom calls
You can make your own methods for custom calls:
<?php
namespace App\Models;
use MdelaRiva\ApiModel\ApiModelAbstract;
class Article extends ApiModelAbstract
{
public static function test( $params )
{
return self::call( [ 'test' ], 'POST', $params );
}
}
- Cache
For storing all GET requests done by a model (global cache flag must be TRUE
or null
), and/or the TTL (in seconds):
<?php
namespace App\Models;
use MdelaRiva\ApiModel\ApiModelAbstract;
class Article extends ApiModelAbstract
{
public $cache = TRUE;
protected $cacheTtl = 30;
}
Pre-built models
Twitter - User
- API Documentation
- Namespace:
MdelaRiva\ApiModel\Models\Twitter\User
Youtube Data API - Channel
- API Documentation
- Namespace:
MdelaRiva\ApiModel\Models\Youtube\Channel
Youtube Data API - Search
- API Documentation
- Namespace:
MdelaRiva\ApiModel\Models\Youtube\Search
Examples
Twitter integration
- Configuration
<?php
return [
'default' => env('APIMODEL_CONNECTION', 'default'),
'connections' => [
'twitter' => [
'url' => 'https://api.twitter.com/',
'version' => '1.1',
'credentials' => [
'useAuthorizationHeader' => TRUE,
'grant_type' => 'client_credentials',
'client_id' => env( 'APIMODEL_CLIENT_ID' ),
'client_secret' => env( 'APIMODEL_CLIENT_SECRET' ),
],
'wrappers' => [
'collection' => [
'root' => 'results',
],
],
],
],
];
- Model
Using manual calls:
<?php
namespace App\Models;
use MdelaRiva\ApiModel\ApiModelAbstract;
class Twitter extends ApiModelAbstract
{
protected $connection = 'twitter';
public function __construct( array $attributes = array() )
{
parent::__construct( $attributes );
$this->setEndpoint( '' );
}
public static function tweetsSearch( $query, $fromDate = null, $maxResults = 10 )
{
$parameters = [
'query' => $query,
'maxResults' => $maxResults,
'fromDate' => $fromDate,
];
return self::call( [ 'tweets/search/30day/testing.json' ], 'GET', $parameters );
}
}
Using pre-built models:
<?php
namespace App\Models;
use MdelaRiva\ApiModel\Models\Twitter\User as TwitterUser;
class User extends TwitterUser
{
protected $connection = 'twitter';
}