Skip to content

Commit ad359e8

Browse files
### 0.2.5
- Documentation
1 parent afe4c8f commit ad359e8

File tree

4 files changed

+307
-5
lines changed

4 files changed

+307
-5
lines changed

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,3 +71,11 @@
7171
- Option to add parameters default values externally
7272
- Documentation shows parameter default values
7373
- Documentation formatting with inline code style for methods and parameters
74+
75+
76+
### 0.2.4
77+
- Made all function protected expect for `importApi` to prevent conflict with api methods
78+
- Started with Documentation
79+
80+
### 0.2.5
81+
- Documentation

README.md

Lines changed: 295 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,299 @@
11
# php-api-client-forge
2-
Create restful API client in PHP with least code
32

3+
Create restful API client from Postman Collection data (or other sources) in PHP with least code.
4+
# php-api-client-forge
5+
6+
- Create restful API client class from Postman Collection data (or other sources)
7+
- Auto generate class `@method` documentation for phpDoc
8+
- Auto generate Markdown API Documentation
9+
10+
11+
12+
[![Latest Stable Version](https://poser.pugx.org/sudiptochoudhury/php-api-client-forge/version)](https://packagist.org/packages/sudiptochoudhury/php-api-client-forge)
13+
[![Latest Unstable Version](https://poser.pugx.org/sudiptochoudhury/php-api-client-forge/v/unstable)](//packagist.org/packages/sudiptochoudhury/php-api-client-forge)
14+
[![License](https://poser.pugx.org/sudiptochoudhury/php-api-client-forge/license)](https://packagist.org/packages/sudiptochoudhury/php-api-client-forge)
15+
[![Total Downloads](https://poser.pugx.org/sudiptochoudhury/php-api-client-forge/downloads)](https://packagist.org/packages/sudiptochoudhury/php-api-client-forge)
16+
[![composer.lock available](https://poser.pugx.org/sudiptochoudhury/php-api-client-forge/composerlock)](https://packagist.org/packages/sudiptochoudhury/php-api-client-forge)
17+
18+
Import API definitions from Postman exported JSON to a JSON compatible with Guzzle\Description format
19+
or pass a `GuzzleHttp\Command\Guzzle\Description` object and
20+
your API class is ready to roll.
21+
22+
> As a bonus, you will also get an auto generated API documentation in markdown format. Moreover, you will get a php
23+
file with `@method` declarations for phpDoc class documentation.
24+
25+
This package needs to be used as parent. Extend the `Client` class to make you own API class.
26+
27+
> This is specially
28+
designed to import Postman collection exported as JSON (Collection v2.1 -
29+
[Schema](https://schema.getpostman.com/json/collection/v2.1.0/collection.json)).
30+
31+
32+
<a name="basics"/>
33+
34+
## Basics
35+
36+
```php
37+
38+
<?php
39+
40+
namespace My\Namespace\ApiProvider;
41+
42+
use SudiptoChoudhury\Support\Forge\Api\Client as ApiForge;
43+
44+
class Api extends ApiForge
45+
{
46+
47+
protected $DEFAULT_API_JSON_PATH = './config/GuzzleDescription.json';
48+
49+
protected $DEFAULTS = [
50+
'AuthToken' => 'xxxxxxxxxxxxxxxxxxxxxxxxxx',
51+
'ClientID' => 'xxxxxxxxxxxxxxx',
52+
'client' => [
53+
'base_uri' => 'https://api.provider.com/api/v1/',
54+
'verify' => false,
55+
'headers' => [
56+
'Authorization' => 'Zoho-authtoken {{AuthToken}}',
57+
'X-com-zoho-subscriptions-organizationid' => "{{ClientID}}",
58+
],
59+
],
60+
];
61+
62+
}
63+
64+
```
65+
That should be it. Nothing else is required. All the API endpoint will be intelligently converted to functions of this
66+
class. For example, if you have an endpoint `[GET]/products`, you will get a `getProducts` function. Here are some more
67+
examples:
68+
69+
| HTTP Method | Endpoint | Converted function name | Parameters | Example call |
70+
|-------------|----------|-------------------------|------------|--------------|
71+
|GET| /products| `getProducts` | none | `$api->getProducts()`|
72+
|GET| /products/{product_id}| `getProduct` | `product_id` | `$api->getProduct(['product_id' => 101])`|
73+
|POST| /products| `addProduct` | a list of params | `$api->addProduct($data)`|
74+
|PUT| /products/{product_id}| updateProduct | `product_id` and a list of other parameters | `$api->updateProduct(['product_id' => 101])`...|
75+
|DELETE| /products/{product_id}| deleteProduct | `product_id` | `$api->deleteProduct(['product_id' => 101])`|
76+
77+
Tried best to normalize the singulars and plurals.
78+
79+
80+
> There can be cases when the API endpoint structure is same as the another but the data passed to it determines a
81+
different action altogether. Ideally, this should not happen but not all API enpoints are ideally created.
82+
So, an endpoint like `[get]/products?filter_by=active` along with another endpoint `[get]/products` will have the
83+
same name. To keep both, the default behaviour is to add an `_` before the duplicate name. However, you can add filters
84+
or hooks to completely change the duplicate name to something else.
85+
86+
87+
<a name="install"/>
88+
89+
## Installation
90+
91+
<a name="requirements"/>
92+
93+
### Requirements
94+
95+
- Any flavour of PHP 7.0+ should do
96+
97+
<a name="install-composer"/>
98+
99+
### Install With Composer
100+
101+
You can install the library via [Composer](http://getcomposer.org) by adding the following line to the
102+
**require** block of your *composer.json* file (replace dev-master with latest stable version):
103+
104+
```
105+
"sudiptochoudhury/php-api-client-forge": "dev-master"
106+
```
107+
108+
or run the following command:
109+
110+
```
111+
composer require sudiptochoudhury/php-api-client-forge
112+
```
113+
114+
<a name="import"/>
115+
116+
## Importing Postman JSON
117+
118+
Export your Postman Collection using COllecton v2.1 format. It will be exported as JSON. Give the file a
119+
name, say `postman.json` and keep it inside a folder in your project.
120+
121+
Next, extend `Import` class (recommended) or may use it directly.
122+
123+
#### By Extending the `Import` class
124+
125+
```php
126+
<?php
127+
namespace My\Namespace\ApiProvider;
128+
129+
use SudiptoChoudhury\Support\Forge\Api\Import as ParentImport;
130+
131+
/**
132+
* Class Import
133+
*
134+
* @package Pour\Package\Name
135+
*/
136+
class Import extends ParentImport
137+
{
138+
139+
protected $DEFAULT_API_JSON_PATH = './config/GuzzleDescription.json';
140+
protected $DEFAULT_SOURCE_JSON_PATH = './config/postman.json';
141+
142+
}
143+
```
144+
You are ready to import. That's pretty much it (though there are tons of configurable options and hooks...
145+
we will come to that soon).
146+
147+
Now, let's import in some other part of your codebase.
148+
149+
```php
150+
<?php
151+
152+
use My\Namespace\ApiProvider\Import;
153+
...
154+
new (Import())->writeDefinition();
155+
...
156+
157+
```
158+
159+
Done!
160+
161+
162+
#### Directly using parent class
163+
164+
It's even simpler (though)
165+
166+
```php
167+
<?php
168+
169+
use SudiptoChoudhury\Support\Forge\Api\Import;
170+
171+
...
172+
new (Import([
173+
'./config/postman.json'
174+
]))->writeDefinition( './config/GuzzleDescription.json');
175+
...
176+
```
177+
178+
Simpler, eh!
179+
180+
You will find a new `.json`, a new `.md` and a new `.php` file to server you well in your API venture forward.
181+
182+
The `.json` file is obviously based on data structure required to create a `GuzzleHttp\Command\Guzzle\Description`
183+
object.
184+
185+
The `.php` file has phpDoc `@method` definitions and may look something similar to
186+
187+
```php
188+
<?php
189+
/**
190+
* @method array getHostedpage(array $parameters) Getting the details of a particular hosted page
191+
* @method array getHostedpages() Listing all the hostedpages
192+
193+
```
194+
You can copy the method definitions parts to yor API class extended from the `Client` class.
195+
196+
The `.md` file is a markdown file with a table containing details of the API functions, equivalent endpoints,
197+
parameters, default values for parameters (if defined) and description - all derived from the Postman json file.
198+
199+
200+
201+
> However, I would recommend to use the extend option as you will get a plethora of options to hook into various
202+
sections of parent code while the conversion of the Postman data to Guzzle Description is undergoing.
203+
You may want to add default values or change a name or change description or skip some items.
204+
All can be done by overriding functions of Import parent class and defining custom filter functions.
205+
206+
207+
<a name="filters"/>
208+
209+
## What are custom filter function?!!!
210+
211+
Well, let's pick an example. Let's say you see you want to change the duplicate function name for `[get]/products` as
212+
I stated an example in previous section. By default, the duplicate name will be set to `_getProducts`
213+
(remember? by default adding a `_` before the name).
214+
215+
Now, in your extended `Import` class just define this
216+
217+
```php
218+
<?php
219+
220+
/** This is a filter
221+
* @param $apiFunctionName
222+
* @param array $helperData
223+
* @return string
224+
*/
225+
public function filterFinalName($apiFunctionName, $helperData = [])
226+
{
227+
if ($apiFunctionName === '_getProducts') {
228+
$apiFunctionName = 'getActiveProducts';
229+
}
230+
return $apiFunctionName;
231+
}
232+
233+
```
234+
235+
This is a filter function. The name must start with `filter` followed by the filter name and can then optionally
236+
add an `_` and anything you want after that, just in case you want to define multiple functions for the same filter
237+
(like - `filterFinalName_xxx` or `filterFinalName_001`).
238+
239+
Each filter function will receive the value to be modified in the first parameter. The optional second parameter
240+
will be an associative array of helper data items that may help in determining logic of how the filter can be applied.
241+
At times it may also be the source of data to build documentation layouts. For example, the markdown API table is
242+
generated via a default filter. You can override it to generate the API table in your own way. May be you do not like
243+
table structure, you may devise you own structure. Sky is the limit. Additionally, there are a lot of filters dedicated
244+
to create a complete markdown documentation with sections like title, menu, description, table, header, footer,
245+
install, even donate and contact. Just tap into the desired layout filters and fill in your own content.
246+
247+
248+
The table below gives you details of all the filters.
249+
250+
> But before that, you can also do similar things by totally overriding the parent's functions. For example,
251+
`readApiName` can be overridden to extend or replace existing login to detect a function name with your own logic.
252+
However, filters help in changing things in a granular way. There can be 10 filters applied to a single
253+
function you wan to override and you may need to just use one filter out of them instead of writing a big bunch of
254+
overriding code. Of course, choice is yours.
4255

256+
| Filter Name | Description |
257+
|-------------|------------- |
258+
| Name | API function name of a single Endpoint |
259+
| Slug | A slug derived from API's name defined in Postmam |
260+
| FinalName | API function name after all logic has been applied |
261+
| Params | Api function parameters |
262+
| Uri | Endpoint |
263+
| Operation | Opetaion data of a single endpoint for Guzzle Description |
264+
| Title | Title of the Postman collection |
265+
| DocMethodFinalText | phpDoc method as joined text |
266+
| DocMDItem | Markdown API for single endpoint details as array |
267+
| DocMDApiExternalLink | Markdown's placeholder for link to external (API service provider's) API Documentation |
268+
| DocMDEndpoint | Endpoint of API item in Markdown documentation |
269+
| DocMDDescription | Description of API item in Markdown documentation |
270+
| DocMDParams | Parameters of API Item Markdown documentation |
271+
| DocMDParamDefaults | Default values for parameres of API item Markdown documentation |
272+
| DocMDLayoutTitle | Markdown documentation title |
273+
| DocMDLayoutSubtitle | Markdown documentation subtitle |
274+
| DocMDLayoutHeader | Markdown documentation header |
275+
| DocMDLayoutMenu | Markdown documentation menu |
276+
| DocMDLayoutDescription | Markdown documentation description |
277+
| DocMDLayoutRequirements | Markdown documentation requirements section |
278+
| DocMDLayoutInstall | Markdown documentation install section |
279+
| DocMDLayoutGetStarted | Markdown documentation gettting started section |
280+
| DocMDLayoutSetup | Markdown documentation setup section |
281+
| DocMDLayoutExamples | Markdown documentation examples section |
282+
| DocMDLayoutTable | Markdown documentation API table section - helper data can be iterated to get data in this structure -`[ 'method' => '\<function name\>', 'endpoint' => '\<endpoint uri\>', 'parameters' => [`\<indexed array\>`], 'defaults' => ['<associative array>'], 'description' => '<api description>']` |
283+
| DocMDLayoutFooter | Markdown documentation footer section |
284+
| DocMDLayoutNotes | Markdown documentation notes section |
285+
| DocMDLayoutReferences | Markdown documentation references section |
286+
| DocMDLayoutContact | Markdown documentation contact us section |
287+
| DocMDLayoutDonate | Markdown documentation donate section |
288+
| DocMDFinalLayoutArray | All Markdown documentation layouts as array |
289+
| DocMDFinalText | Full Markdown documentation as text |
290+
| APIDefinitionFinalJson | The full Guzzle Description |
291+
| DocMethodItem | phpDoc method for single endpoint |
292+
| DocMethodDescription | Markdown documentation |
293+
| DocMethodFinalArray | All phpDoc methods as array |
294+
| DocMethodParams | Parameters for phpDoc |
295+
| DocMethodData | What needs to shown in the parenthesis of the method signature in phpDoc |
296+
| DocMethodSignature | Full single method signature for phpDoc |
297+
| GroupName | Postman Collection's Group Name |
298+
| GroupDescription | Post Collection's Description |
5299

src/support/forge/api/Client.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ public function __construct($config = [])
6363
*
6464
* @return $this
6565
*/
66-
public function setOptions($options = [])
66+
protected function setOptions($options = [])
6767
{
6868
$myProperties = get_class_vars(__CLASS__);
6969
$myDefaults = $myProperties['DEFAULTS'];
@@ -115,7 +115,7 @@ protected function parseOptions($options, $rootOption = [])
115115
*
116116
* @return $this
117117
*/
118-
public function setDescription($descriptionOptions = [])
118+
protected function setDescription($descriptionOptions = [])
119119
{
120120

121121
$optionsJsonPath = $this->options['description']['jsonPath'];
@@ -158,7 +158,7 @@ public function setDescription($descriptionOptions = [])
158158
*
159159
* @return $this
160160
*/
161-
public function createClient($clientOptions = [])
161+
protected function createClient($clientOptions = [])
162162
{
163163
$this->client = new GHClient($clientOptions);
164164
return $this;

src/support/forge/api/Import.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ protected function importFromJson($filePath)
122122
$commonParams['phpDocMethod'] = $methods[$apiName] = $this->readPhpDocMethodItem($commonParams);
123123
}
124124
if (($skipConfig['mdDoc'] ?? ($skipConfig['docs'] ?? true)) !== false) {
125-
$docs[$apiGroupName]['items'][$apiName] =$this->readMarkdownItem($commonParams);
125+
$docs[$apiGroupName]['items'][$apiName] = $this->readMarkdownItem($commonParams);
126126
}
127127
}
128128
}

0 commit comments

Comments
 (0)