Skip to content

Resolve: Consider OpenAPI spec examples in faker code generation #20 #21

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
2f9aa2e
Initial commit to create a PR
SOHELAHMED7 Aug 1, 2024
fa7c240
Implement for multiple data types
SOHELAHMED7 Aug 2, 2024
c0405e8
Implement faker generation of array - WIP
SOHELAHMED7 Aug 6, 2024
701d612
WIP 2
SOHELAHMED7 Aug 8, 2024
5b87057
Implement for object and obj with array & nested object - WIP
SOHELAHMED7 Aug 8, 2024
46b8d48
Implement for object and obj with nested array & nested object
SOHELAHMED7 Aug 9, 2024
c1bc831
Implement faker generation for array of referenced component schema
SOHELAHMED7 Aug 9, 2024
2f08c41
Implement oneOf and refactor - WIP
SOHELAHMED7 Aug 13, 2024
9f83e78
Implement oneOf and refactor - WIP 2
SOHELAHMED7 Aug 13, 2024
b3c660b
Implement oneOf and refactor - WIP 3
SOHELAHMED7 Aug 13, 2024
1e7cea6
Complex oneOf - WIP
SOHELAHMED7 Aug 13, 2024
14b2146
Implement complex oneOf + fix error 'Creating default object from emp…
SOHELAHMED7 Aug 14, 2024
4e6bc03
Fix failing test for x_db_type
SOHELAHMED7 Aug 14, 2024
b2c21d1
Fix bug
SOHELAHMED7 Aug 14, 2024
52f2320
Fix failing test
SOHELAHMED7 Aug 14, 2024
b037265
Fix failing test
SOHELAHMED7 Aug 15, 2024
0910073
Fix errors
SOHELAHMED7 Aug 15, 2024
f0c5cd3
Fix errors 2 + implement custom attribute `x-no-relation`
SOHELAHMED7 Aug 15, 2024
de75ca7
Fix failing test in PHP >= 8.1
SOHELAHMED7 Aug 16, 2024
6ab30cc
Fix count issue for nested array
SOHELAHMED7 Aug 16, 2024
960cc43
Add typehint to fn args
SOHELAHMED7 Aug 16, 2024
4f6d728
Fix issues + add support for all refs only in oneOf
SOHELAHMED7 Aug 16, 2024
65625f0
Refactor
SOHELAHMED7 Aug 17, 2024
77f6ff2
Fix bug
SOHELAHMED7 Aug 17, 2024
ee6f7ec
Add docs for `x-no-relation` and create its constant
SOHELAHMED7 Aug 17, 2024
6cfadcf
Handle example
SOHELAHMED7 Aug 17, 2024
b3023c4
Add test spec file
SOHELAHMED7 Aug 17, 2024
775ff26
Enhance docs
SOHELAHMED7 Aug 17, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ up:
cli:
docker-compose exec --user=$(UID) php bash

cli_root:
docker-compose exec --user="root" php bash

cli_mysql:
docker-compose exec --user=$(UID) mysql bash

Expand Down
67 changes: 62 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,9 @@ return $config;

To use the web generator, open `index.php?r=gii` and select the `REST API Generator`.

On console you can run the generator with `./yii gii/api --openApiPath=@app/openapi.yaml`. Where `@app/openapi.yaml` should be the absolute path to your OpenAPI spec file. This can be JSON as well as YAML (see also [php-openapi/php-openapi](https://github.com/php-openapi/php-openapi/) for supported formats).
On console, you can run the generator with `./yii gii/api --openApiPath=@app/openapi.yaml`. Where `@app/openapi.yaml`
should be the absolute path to your OpenAPI spec file. This can be JSON as well as YAML (see
also [php-openapi/php-openapi](https://github.com/php-openapi/php-openapi/) for supported formats).

Run `./yii gii/api --help` for all options. Example: Disable generation of migrations files `./yii gii/api --generateMigrations=0`

Expand Down Expand Up @@ -309,15 +311,69 @@ Provide custom database table column name in case of relationship column. This w
- x-fk-column-name: redelivery_of # this will create `redelivery_of` column instead of `redelivery_of_id`
```

### `x-no-relation`

To differentiate a component schema property from one-to-many or many-to-many relation in favour of array(json) of
related objects, `x-no-relation` (type: boolean, default: false) is used.

```yaml
comments:
type: array
items:
$ref: "#/components/schemas/Comment"
```

This will not generate 'comments' column in database migrations. But it will generate `getComments()` relation in Yii model file.

In order to make it real database column, extension `x-no-relation` can be used.

```yaml
comments:
type: array
x-no-relation: true
items:
$ref: "#/components/schemas/Comment"
```

Database column type can be `array`, `json` etc. to store such data.

Now if the Comment schema from the above example is

```yaml
Comment:
properties:
id:
type: integer
content:
type: string
```

then the value for `comments` can be

```json
[
{
"id": 1,
"content": "Hi there"
},
{
"id": 2,
"content": "Hi there 2"
}
]
```

`x-no-relation` can be only used with OpenAPI schema data type `array`.

## Many-to-Many relation definition

There are two ways for define many-to-many relations:

### Simple many-to-many without junction model

- property name for many-to-many relation should be equal lower-cased, pluralized related schema name
- referenced schema should contains mirrored reference to current schema

- referenced schema should contain mirrored reference to current schema

- migration for junction table can be generated automatically - table name should be [pluralized, lower-cased
schema_name1]2[pluralized, lower-cased schema name2], in alphabetical order;
Expand Down Expand Up @@ -508,12 +564,13 @@ created_at:
## Assumptions

When generating code from an OpenAPI description there are many possible ways to achive a fitting result.
Thus there are some assumptions and limitations that are currently applied to make this work.
Thus, there are some assumptions and limitations that are currently applied to make this work.
Here is a (possibly incomplete) list:

- The current implementation works best with OpenAPI description that follows the [JSON:API](https://jsonapi.org/) guidelines.
- The request and response format/schema is currently not extracted from OpenAPI schema and may need to be adjusted manually if it does not follow JSON:API
- column/field/property with name `id` is considered as Primary Key by this library and it is automatically handled by DB/Yii; so remove it from validation `rules()`
- column/field/property with name `id` is considered as Primary Key by this library, and it is automatically handled by
DB/Yii; so remove it from validation `rules()`
- other fields can currently be used as primary keys using the `x-pk` OpenAPI extension (see below) but it may not be work correctly in all cases, please report bugs if you find them.

Other things to keep in mind:
Expand Down
5 changes: 3 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,14 @@
},
"require": {
"php": "^7.4 || ^8.0",
"cebe/php-openapi": "^1.5.0",
"yiisoft/yii2": "~2.0.48",
"yiisoft/yii2-gii": "~2.0.0 | ~2.1.0 | ~2.2.0| ~2.3.0",
"laminas/laminas-code": ">=3.4 <=4.13",
"php-openapi/yii2-fractal": "^1.0.0",
"fakerphp/faker": "^1.9",
"sam-it/yii2-mariadb": "^2.0"
"sam-it/yii2-mariadb": "^2.0",
"symfony/var-exporter": "^5.4",
"cebe/php-openapi": "^1.7"
},
"require-dev": {
"cebe/indent": "*",
Expand Down
15 changes: 10 additions & 5 deletions src/lib/AttributeResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@

namespace cebe\yii2openapi\lib;

use cebe\yii2openapi\lib\Config;
use cebe\yii2openapi\lib\CustomSpecAttr;
use cebe\yii2openapi\lib\exceptions\InvalidDefinitionException;
use cebe\yii2openapi\lib\items\Attribute;
use cebe\yii2openapi\lib\items\AttributeRelation;
Expand All @@ -22,7 +20,6 @@
use Yii;
use yii\helpers\Inflector;
use yii\helpers\StringHelper;
use yii\helpers\VarDumper;
use function explode;
use function strpos;
use function strtolower;
Expand Down Expand Up @@ -220,15 +217,22 @@ protected function resolveProperty(
$nullableValue = $property->getProperty()->getSerializableData()->nullable ?? null;
}
$attribute = Yii::createObject(Attribute::class, [$property->getName()]);

if (!empty($property->getAttr(CustomSpecAttr::NO_RELATION))) {
$this->attributes[$property->getName()] = $attribute->setFakerStub($this->guessFakerStub($attribute, $property));
}

$attribute->setRequired($isRequired)
->setPhpType($property->guessPhpType())
->setDescription($property->getAttr('description', ''))
->setReadOnly($property->isReadonly())
->setDefault($property->guessDefault())
->setXDbType($property->getAttr(CustomSpecAttr::DB_TYPE))
->setXDbDefaultExpression($property->getAttr(CustomSpecAttr::DB_DEFAULT_EXPRESSION))
->setNullable($nullableValue)
->setIsPrimary($property->isPrimaryKey())
->setForeignKeyColumnName($property->fkColName);
->setForeignKeyColumnName($property->fkColName)
->setFakerStub($this->guessFakerStub($attribute, $property));
if ($property->isReference()) {
if ($property->isVirtual()) {
throw new InvalidDefinitionException('References not supported for virtual attributes');
Expand Down Expand Up @@ -262,7 +266,8 @@ protected function resolveProperty(
->setSize($fkProperty->getMaxLength())
->setDescription($property->getRefSchema()->getDescription())
->setDefault($fkProperty->guessDefault())
->setLimits($min, $max, $fkProperty->getMinLength());
->setLimits($min, $max, $fkProperty->getMinLength())
->setFakerStub($this->guessFakerStub($attribute, $property));

$relation = Yii::createObject(
AttributeRelation::class,
Expand Down
5 changes: 5 additions & 0 deletions src/lib/CustomSpecAttr.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,9 @@ class CustomSpecAttr
* Foreign key column name. See README for usage docs
*/
public const FK_COLUMN_NAME = 'x-fk-column-name';

/**
* Foreign key column name. See README for usage docs
*/
public const NO_RELATION = 'x-no-relation';
}
Loading
Loading