Recommend this page to a friend! |
![]() |
Info | Documentation | ![]() |
![]() |
![]() |
Reputation | Support forum | Blog | Links |
Last Updated | Ratings | Unique User Downloads | Download Rankings | |||||
2025-06-03 (Less than 1 hour ago) ![]() | Not enough user ratings | Total: 27 | All time: 11,217 This week: 40![]() |
Version | License | PHP version | Categories | |||
openswoole-microserv 1.0.18 | MIT/X Consortium ... | 8 | HTTP, Libraries, Design Patterns, Per... |
This is a light & easy Openswoole based low code API generator using configuration arrays. It can be used to create APIs in a very short time once you are done with your database.
*
> Note: One can import all three sql's in a single database to start with. Just configure the same details in the .env file.
Below are the configuration settings details in .env
ENVIRONMENT=0 ;Environment PRODUCTION = 1 / DEVELOPMENT = 0
OUTPUT_PERFORMANCE_STATS=1 ;Add Performance Stats in Json output: 1 = true / 0 = false
allowConfigRequest=1 ;Allow config request (global flag): 1 = true / 0 = false
cronRestrictedIp='127.0.0.1' ;Crons Details
maxPerpage=10000 ;Maximum value of perpage (records per page)
cacheType='Redis'
cacheHostname='127.0.0.1'
cachePort=6379
cacheUsername='ramesh'
cachePassword='shames11'
cacheDatabase=0
globalType='MySql'
globalHostname='127.0.0.1'
globalPort=3306
globalUsername='root'
globalPassword='shames11'
globalDatabase='global'
groups='m002_master_groups'
clients='m001_master_clients'
defaultDbType='MySql'
defaultDbHostname='127.0.0.1'
defaultDbPort=3306
defaultDbUsername='root'
defaultDbPassword='shames11'
defaultDbDatabase='global'
dbDatabaseClient001='client_001'
dbHostnameClient001='127.0.0.1'
dbUsernameClient001='root'
dbPasswordClient001='shames11'
dbDatabaseClient001='client_001'
clientMasterDbName='client_master' ;contains all entities required for a new client.
client_users='master_users' ;Table in client database containing user details.
These DB/Cache configurations can be set in below columns respectively for each client.
`m001_master_clients`.`master_db_server_type` varchar(255) NOT NULL,
`m001_master_clients`.`master_db_hostname` varchar(255) NOT NULL,
`m001_master_clients`.`master_db_port` varchar(255) NOT NULL,
`m001_master_clients`.`master_db_username` varchar(255) NOT NULL,
`m001_master_clients`.`master_db_password` varchar(255) NOT NULL,
`m001_master_clients`.`master_db_database` varchar(255) NOT NULL,
`m001_master_clients`.`slave_db_server_type` varchar(255) NOT NULL,
`m001_master_clients`.`slave_db_hostname` varchar(255) NOT NULL,
`m001_master_clients`.`slave_db_port` varchar(255) NOT NULL,
`m001_master_clients`.`slave_db_username` varchar(255) NOT NULL,
`m001_master_clients`.`slave_db_password` varchar(255) NOT NULL,
`m001_master_clients`.`slave_db_database` varchar(255) NOT NULL,
`m001_master_clients`.`master_cache_server_type` varchar(255) NOT NULL,
`m001_master_clients`.`master_cache_hostname` varchar(255) NOT NULL,
`m001_master_clients`.`master_cache_port` varchar(255) NOT NULL,
`m001_master_clients`.`master_cache_username` varchar(255) NOT NULL,
`m001_master_clients`.`master_cache_password` varchar(255) NOT NULL,
`m001_master_clients`.`master_cache_database` varchar(255) NOT NULL,
`m001_master_clients`.`slave_cache_server_type` varchar(255) NOT NULL,
`m001_master_clients`.`slave_cache_hostname` varchar(255) NOT NULL,
`m001_master_clients`.`slave_cache_port` varchar(255) NOT NULL,
`m001_master_clients`.`slave_cache_username` varchar(255) NOT NULL,
`m001_master_clients`.`slave_cache_password` varchar(255) NOT NULL,
`m001_master_clients`.`slave_cache_database` varchar(255) NOT NULL,
; ---- Rate Limit Server Details (Redis)
;used to save Rate Limiting related details
RateLimiterHost='127.0.0.1' ; Redis host dealing with Rate limit
RateLimiterHostPort=6379 ; Redis host port
RateLimiterIPMaxRequests=600 ; Max request allowed per IP
RateLimiterIPSecondsWindow=300 ; Window in seconds of Max request allowed per IP
RateLimiterIPPrefix='IPRL:' ; Rate limit open traffic (not limited by allowed IPs/CIDR and allowed Rate Limits to users)
RateLimiterClientPrefix='CRL:' ; Client based Rate Limitng (GRL) key prefix used in Redis
RateLimiterGroupPrefix='GRL:' ; Group based Rate Limitng (GRL) key prefix used in Redis
RateLimiterUserPrefix='URL:' ; User based Rate Limitng (URL) key prefix used in Redis
# Client level
`m001_master_clients`.`rateLimiterMaxRequests` int DEFAULT NULL,
`m001_master_clients`.`rateLimiterSecondsWindow` int DEFAULT NULL,
# Group level
`m002_master_groups`.`rateLimiterMaxRequests` int DEFAULT NULL,
`m002_master_groups`.`rateLimiterSecondsWindow` int DEFAULT NULL,
# User level
`master_users`.`rateLimiterMaxRequests` int DEFAULT NULL,
`master_users`.`rateLimiterSecondsWindow` int DEFAULT NULL,
RateLimiterRoutePrefix='RRL:' ; Route based Rate Limiting (RRL) key prefix used in Redis
return [
[...]
'rateLimiterMaxRequests' => 1, // Allowed number of requests
'rateLimiterSecondsWindow' => 3600, // Window in Seconds for allowed number of requests
[...]
];
<GroupName> is the group user belongs to for accessing the API's
For configuring route /tableName/parts GET method
return [
'tableName' => [
'parts' => [
'__FILE__' => 'SQL file location'
]
]
];
For configuring route /tableName/{id} where id is dynamic integer value to be collected.
return [
'tableName' => [
'{id:int}' => [
'__FILE__' => 'SQL file location'
]
]
];
Same dynamic variable but with a different data type, for e.g. {id} will be treated differently for string and integer values to be collected.
return [
'tableName' => [
'{id:int}' => [
'__FILE__' => 'SQL file location for integer data type'
],
'{id:string}' => [
'__FILE__' => 'SQL file location for string data type'
]
]
];
To restrict dynamic values to a certain set of values. One can do the same by appending comma-separated values after OR key.
return [
'{tableName:string|admin,group,client,routes}' => [
'{id:int}' => [
'__FILE__' => 'SQL file location'
]
]
];
On other side; to exclude dynamic values. One can do the same by prefixing NOT(!) synbol to comma-separated values.
return [
'{tableName:string}' => [
'{id:int|!0}' => [
'__FILE__' => 'SQL file location'
]
]
];
> Hooks
return [
'{tableName:string}' => [
'__FILE__' => 'SQL file location',
'__PRE-ROUTE-HOOKS__' => [// These will apply recursively
'Hook_1',
'...'
],
'__POST-ROUTE-HOOKS__' => [// These will apply recursively
'Hook_1',
'...'
]
'{id:int|!0}' => [
'__FILE__' => 'SQL file location',
'__PRE-ROUTE-HOOKS__' => [], // For noi hooks
'__POST-ROUTE-HOOKS__' => [] // For noi hooks
]
]
];
> This '{id:int|!0}' means id is integer but can't be zero.
> One can replace <filenames> tag with desired name as per functionality.
static public $CustomINT = [
// Required param
// PHP data type (bool, int, float, string)
'dataType' => 'int',
// Optional params
// Minimum value (int)
'minValue' => false,
// Maximum value (int)
'maxValue' => false,
// Minimum length (string)
'minLength' => false,
// Maximum length (string)
'maxLength' => false,
// Any one value from the Array
'enumValues' => false,
// Values belonging to this Array
'setValues' => false,
// Values should pass this regex before use
'regex' => false
];
//return represents root for sqlResults
return [
// Required to implementing pagination
'countQuery' => "SELECT count(1) as `count` FROM TableName WHERE __WHERE__", // OR
'countQuery' => "SELECT count(1) as `count` FROM TableName WHERE column1 = :column1 AND id = :id",
// Query to perform task
'__QUERY__' => "SELECT columns FROM TableName WHERE __WHERE__", // OR
'__QUERY__' => "SELECT columns FROM TableName WHERE column1 = :column1 AND id = :id",
// Details of data to be set by Query to perform task
'__SET__' => [
[ // Fatch value from parsed route
'column' => 'id',
'fetchFrom' => 'uriParams', // uriParams / payload
'fetchFromValue' => 'id', // key (id)
'dataType' => DatabaseDataTypes::$PrimaryKey, // key data type
'required' => Constants::$REQUIRED // Represents required field
],
[ // Fatch value from payload
'column' => 'id',
'fetchFrom' => 'payload', // payload
'fetchFromValue' => '<key>', // key (<key>)
],
[ // Fatch value from function
'column' => 'password',
'fetchFrom' => 'function', // function
'fetchFromValue' => function($session) { // execute a function and return value
return 'value';
}
],
[ // Fatch value from userDetails session
'column' => 'user_id',
'fetchFrom' => 'userDetails', // userDetails from session
'fetchFromValue' => 'user_id' // user_id Key
],
[ // Fatch value of last insert ids
'column' => 'is_deleted',
'fetchFrom' => 'custom', // custom
'fetchFromValue' => '<static-value>' // Static values
]
],
// Where clause of the Query to perform task
'__WHERE__' => [
[ // Fatch value from parsed route
'column' => 'id',
'fetchFrom' => 'uriParams', // uriParams / payload
'fetchFromValue' => 'id', // key (id)
'dataType' => DatabaseDataTypes::$PrimaryKey, // key data type
'required' => Constants::$REQUIRED // Represents required field
],
[ // Fatch value from payload
'column' => 'id',
'fetchFrom' => 'payload', // payload
'fetchFromValue' => '<key>', // key (<key>)
],
[ // Fatch value from function
'column' => 'password',
'fetchFrom' => 'function', // function
'fetchFromValue' => function($session) { // execute a function and return value
return 'value';
}
],
[ // Fatch value from userDetails session
'column' => 'user_id',
'fetchFrom' => 'userDetails', // userDetails from session
'fetchFromValue' => 'user_id' // user_id Key
],
[ // Fatch value of last insert ids
'column' => 'is_deleted',
'fetchFrom' => 'custom', // custom
'fetchFromValue' => '<static-value>' // Static values
]
],
// Last insert id to be made available as $session['__INSERT-IDs__'][uniqueParamString];
'__INSERT-IDs__' => '<keyName>:id',
// Indicator to generate JSON in Single(Object) row / Mulple(Array) rows format.
'__MODE__' => 'singleRowFormat/multipleRowFormat',
// subQuery is a keyword to perform recursive operations
/ Supported configuration for recursive operations are :
* __QUERY__,
* __SET__,
* __WHERE__,
* __MODE__,
* __SUB-QUERY__,
* __INSERT-IDs__,
* __TRIGGERS__,
* __PRE-SQL-HOOKS__,
* __POST-SQL-HOOKS__,
* __VALIDATE__,
* __PAYLOAD-TYPE__,
* __MAX-PAYLOAD-OBJECTS__,
*/
'__SUB-QUERY__' => [
'<sub-key>' => [
// Query to perform task
'__QUERY__' => "SQL",
'__SET__/__WHERE__' => [
[...]
// Database DataTypes settings required when useHierarchy is true
// to validate each data set before procedding forward
[ // Fatch value of last insert ids
'column' => 'user_id',
'fetchFrom' => '__INSERT-IDs__', // userDetails from session
'fetchFromValue' => '<saved-id-key>' // previous Insert ids
],
[ // Fatch values of params from previous queries
'column' => 'user_id',
'fetchFrom' => 'sqlParams', // sqlParams (with useHierarchy)
'fetchFromValue' => '<return:keys-seperated-by-colon>'
],
[ // Fatch values of sql results from previous queries
'column' => 'user_id',
'fetchFrom' => 'sqlResults', // sqlResults for DQL operations (with useResultSet)
'fetchFromValue' => '<return:keys-seperated-by-colon>'
],
[ // Fatch values of sql payload for previous queries
'column' => 'user_id',
'fetchFrom' => 'sqlPayload', // sqlPayload (with useHierarchy)
'fetchFromValue' => '<return:keys-seperated-by-colon>'
],
],
'__TRIGGERS__' => [...],
'__PRE-SQL-HOOKS__' => [...],
'__POST-SQL-HOOKS__' => [...],
'__VALIDATE__' => [...],
'__PAYLOAD-TYPE__' => 'Object/Array',
'__MAX-PAYLOAD-OBJECTS__' => 'Integer',
'__SUB-QUERY__' => [...],
],
'<sub-key>' => [
[...]
],
[...]
],
// Trigger set of routes
'__TRIGGERS__' => [// Array of triggers
[
'__ROUTE__' => [
['fetchFrom' => 'custom', 'fetchFromValue' => 'address'],
['fetchFrom' => '__INSERT-IDs__', 'fetchFromValue' => 'address:id']
],
'__QUERY-STRING__' => [
['column' => 'param-1', 'fetchFrom' => 'custom', 'fetchFromValue' => 'address'],
['column' => 'param-2', 'fetchFrom' => '__INSERT-IDs__', 'fetchFromValue' => 'address:id']
],
'__METHOD__' => 'PATCH',
'__PAYLOAD__' => [
['column' => 'address', 'fetchFrom' => 'custom', 'fetchFromValue' => 'updated-address']
]
]
[...]
],
// Hooks
'__PRE-SQL-HOOKS__' => [// Array of Hooks class name in exec order
'Hook_Example1',
'...'
],
'__POST-SQL-HOOKS__' => [// Array of Hooks class name in exec order
'Hook_Example2',
'...'
],
// Array of validation functions to be performed
'__VALIDATE__' => [
[
'fn' => 'validateGroupId',
'fnArgs' => [
'group_id' => ['payload', 'group_id']
],
'errorMessage' => 'Invalid Group Id'
],
[...]
],
'__PAYLOAD-TYPE__' => 'Object', // Allow single "Object" / "Array" of Object (if not set will accept both)
'__MAX-PAYLOAD-OBJECTS__' => 2, // Max number of allowed Objects if __PAYLOAD-TYPE__ is 'Array'
'isTransaction' => false, // Flag to follow transaction Begin, Commit and rollback on error
'useHierarchy' => true, // For DML
'useResultSet' => true, // For DQL
// Rate Limiting Route access
'rateLimiterMaxRequests' => 1, // Allowed number of request in defined seconds window
'rateLimiterSecondsWindow' => 3600, // Seconds Window for restricting number of request
// Control response time as per number of hits by configuring lags in seconds as below
'responseLag' => [
// No of Requests => Seconds Lag
0 => 0,
2 => 10,
],
// Any among below can be used for DML operations (These are Optional keys)
// Caching
'cacheKey' => '<unique-key-for-redis-to-cache-results>(e.g, key:1)', // Use cacheKey to cache and reuse results (Optional)
'affectedCacheKeys' => [ // List down keys which effects configured cacheKey on DML operation
'<unique-key-for-redis-to-drop-cached-results>(key:1)',
'<unique-key-for-redis-to-drop-cached-results>(category etc.)',
'...'
],
// Limiting duplicates
'idempotentWindow' => 3 // Idempotent Window for DML operartion (seconds)
];
> Note: 'useHierarchy' => true also includes 'useResultSet' => true feature.
> If there are repeated modules or configurations; one can reuse them by palcing them in a separate file and including as below.
'__SUB-QUERY__' => [
//Here the module1 properties are reused for write operation.
'module1' => include $Constants::$DOC_ROOT . DIRECTORY_SEPARATOR . 'Config/Queries/ClientDB/Common/reusefilename.php',
]
> For POST, PUT, PATCH, and DELETE methods one can configure both INSERT as well as UPDATE queries if required for sub modules.
Classless Inter-Domain Routing (CIDR) is a method for assigning IP addresses to devices on the internet. Multiple CIDR seperated by comma can be set in (groups table) in global database.
`m002_master_groups`.`allowed_ips` text
One can configure Rate Limiting server details in .env file.
RateLimiterHost='127.0.0.1' ; Redis host dealing with Rate limit
RateLimiterHostPort=6379 ; Redis host port
RateLimiterIPMaxRequests=600 ; Max request allowed per IP
RateLimiterIPSecondsWindow=300 ; Window in seconds of Max request allowed per IP
RateLimiterIPPrefix='IPRL:' ; IP based Rate Limitng (IPRL) key prefix used in Redis
RateLimiterClientPrefix='CRL:' ; Client based Rate Limitng (GRL) key prefix used in Redis
RateLimiterGroupPrefix='GRL:' ; Group based Rate Limitng (GRL) key prefix used in Redis
RateLimiterUserPrefix='URL:' ; User based Rate Limitng (URL) key prefix used in Redis
RateLimiterRoutePrefix='RRL:' ; Route based Rate Limiting (RRL) key prefix used in Redis
One can set these details for respective group in m002_master_groups table of global database
`m002_master_groups`.`rateLimiterMaxRequests` int DEFAULT NULL
`m002_master_groups`.`rateLimiterSecondsWindow` int DEFAULT NULL
One can set these details for respective user in master_users table of respective client database
`master_users`.`rateLimiterMaxRequests` int DEFAULT NULL
`master_users`.`rateLimiterSecondsWindow` int DEFAULT NULL
> DEFAULT NULL represents "no restrictions"
> One can clean the URL by making the required changes in the web server .conf file.
Requires countQuery SQL in the configuration for GET request
defaultPerpage=10
maxPerpage=1000
>One need to urlencode orderBy value
var payload = {
"key1": "value1",
"key2": "value2",
...
};
var payload = [
{
"key1": "value1",
"key2": "value2",
...
},
{
"key1": "value1",
"key2": "value2",
...
},
...
];
'parent_id' => ['sqlResults', 'return:id'],
return [
'__QUERY__' => "INSERT INTO `category` SET __SET__",
'__SET__' => [
'name' => ['payload', 'name'],
'parent_id' => ['custom', 0],
],
'__INSERT-IDs__' => 'category:id',
'__SUB-QUERY__' => [
'module1' => [
'__QUERY__' => "INSERT INTO `category` SET __SET__",
'__SET__' => [
'name' => ['payload', 'subname'],
'parent_id' => ['__INSERT-IDs__', 'category:id'],
],
'__INSERT-IDs__' => 'sub:id',
]
],
'useHierarchy' => true
];
var payload = {
"name":"name",
"module1": {
"subname":"subname",
}
}
var payload = {
"name":"name",
"module1":
[
{
"subname":"subname1",
},
{
"subname":"subname2",
},
...
]
}
var payload = [
{
"name":"name1",
"module1":
[
{
"subname":"subname1",
},
{
"subname":"subname2",
},
...
]
},
{
"name":"name2",
"module1":
[
{
"subname":"subname21",
},
{
"subname":"subname22",
},
...
]
},
...
]
Examples:
One need to enable same in .env file as below
allowConfigRequest=1
configRequestUriKeyword='config' ;for appending /config at end of URI
>For controlling globally there is a flag in env file labled allowConfigRequest
This lists down all allowed routes for HTTP methods respectively.
var handlerUrl = "http://127.0.0.1:9501?r=/login";
var xmlhttp = new XMLHttpRequest();
xmlhttp . open( "POST", handlerUrl );
xmlhttp . setRequestHeader('X-API-Version', 'v1.0.0');
xmlhttp . setRequestHeader('Content-type', 'application/x-www-form-urlencoded; charset=utf-8');
xmlhttp . onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var responseJson = this.responseText;
var responseArr = JSON.parse(responseJson);
console.log(responseArr);
var token = responseArr['Output']['Results']['Token'];
console.log(token);
}
};
// Payload data which is to be made available on the server for the "/ajax-handler".
var payload = {
"username":"client_1_user_1",
"password":"shames11"
};
var jsonString = JSON.stringify(payload);
var urlencodeJsonString = encodeURIComponent(jsonString);
var params = "Payload="+urlencodeJsonString;
xmlhttp . send( params );
var handlerUrl = "http://127.0.0.1:9501?r=/routes";
var xmlhttp = new XMLHttpRequest();
xmlhttp . open( "GET", handlerUrl );
xmlhttp . setRequestHeader('X-API-Version', 'v1.0.0');
xmlhttp . setRequestHeader('Content-type', 'text/plain; charset=utf-8');
xmlhttp . setRequestHeader('Authorization', 'Bearer <Token-from-login-api>');
xmlhttp . onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var responseJson = this.responseText;
var responseArr = JSON.parse(responseJson);
console.log(responseArr);
}
};
xmlhttp . send();
var handlerUrl = "http://127.0.0.1:9501?r=/ajax-handler-route";
var xmlhttp = new XMLHttpRequest();
xmlhttp . open( "POST", handlerUrl );
xmlhttp . setRequestHeader('X-API-Version', 'v1.0.0');
xmlhttp . setRequestHeader('Content-type', 'application/x-www-form-urlencoded; charset=utf-8');
xmlhttp . setRequestHeader('Authorization', ?Bearer <Token-from-login-api>');
xmlhttp . onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var responseJson = this.responseText;
var responseArr = JSON.parse(responseJson);
console.log(responseArr);
}
};
// Payload data which is to be made available on the server for the "/ajax-handler".
var payload = {
"key1": "value1",
"key2": "value2",
};
var jsonString = JSON.stringify(payload);
var urlencodeJsonString = encodeURIComponent(jsonString);
var params = "Payload="+urlencodeJsonString;
xmlhttp . send( params );
var handlerUrl = "http://127.0.0.1:9501?r=/custom/password";
var xmlhttp = new XMLHttpRequest();
xmlhttp . open( "PUT", handlerUrl );
xmlhttp . setRequestHeader('X-API-Version', 'v1.0.0');
xmlhttp . setRequestHeader('Content-type', 'application/x-www-form-urlencoded; charset=utf-8');
xmlhttp . setRequestHeader('Authorization', ?Bearer <Token-from-login-api>');
xmlhttp . onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var responseJson = this.responseText;
var responseArr = JSON.parse(responseJson);
console.log(responseArr);
}
};
// Payload data which is to be made available on the server for the "/ajax-handler".
var payload = {
"old_password": "shames11",
"new_password": "ramesh",
};
var jsonString = JSON.stringify(payload);
var urlencodeJsonString = encodeURIComponent(jsonString);
var params = "Payload="+urlencodeJsonString;
xmlhttp . send( params );
![]() |
File | Role | Description | ||
---|---|---|---|---|
![]() |
||||
![]() |
||||
![]() |
||||
![]() |
||||
![]() |
||||
![]() |
||||
![]() ![]() |
Data | Auxiliary data | ||
![]() ![]() |
Data | Auxiliary data | ||
![]() ![]() |
Data | Auxiliary data | ||
![]() ![]() |
Data | Auxiliary data | ||
![]() ![]() |
Lic. | License text | ||
![]() ![]() |
Doc. | Documentation | ||
![]() |
Class | Class source | ||
![]() |
Class | Class source | ||
![]() ![]() |
Aux. | Configuration script |
The PHP Classes site has supported package installation using the Composer tool since 2013, as you may verify by reading this instructions page. |
![]() |
Version Control | Unique User Downloads | Download Rankings | |||||||||||||||
100% |
|
|
Applications that use this package |
If you know an application of this package, send a message to the author to add a link here.