{"id":15578496,"url":"https://github.com/asseco-voice/laravel-open-api","last_synced_at":"2025-08-15T20:50:42.740Z","repository":{"id":40485460,"uuid":"299838936","full_name":"asseco-voice/laravel-open-api","owner":"asseco-voice","description":"OpenAPI 3.0. generator for Laravel 8","archived":false,"fork":false,"pushed_at":"2024-12-03T02:51:12.000Z","size":362,"stargazers_count":11,"open_issues_count":5,"forks_count":2,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-03-29T03:32:00.575Z","etag":null,"topics":["laravel","laravel-8","laravel-8-package","openapi","openapi-generator","openapi3","php","php7"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/asseco-voice.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-09-30T07:16:22.000Z","updated_at":"2024-06-25T15:23:31.000Z","dependencies_parsed_at":"2024-11-06T18:29:24.847Z","dependency_job_id":null,"html_url":"https://github.com/asseco-voice/laravel-open-api","commit_stats":{"total_commits":76,"total_committers":4,"mean_commits":19.0,"dds":0.2763157894736842,"last_synced_commit":"46681389ddbbac200aa4802624d085782221155e"},"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/asseco-voice%2Flaravel-open-api","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/asseco-voice%2Flaravel-open-api/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/asseco-voice%2Flaravel-open-api/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/asseco-voice%2Flaravel-open-api/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/asseco-voice","download_url":"https://codeload.github.com/asseco-voice/laravel-open-api/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249080485,"owners_count":21209535,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["laravel","laravel-8","laravel-8-package","openapi","openapi-generator","openapi3","php","php7"],"created_at":"2024-10-02T19:10:56.796Z","updated_at":"2025-04-16T01:28:13.816Z","avatar_url":"https://github.com/asseco-voice.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\u003ca href=\"https://see.asseco.com\" target=\"_blank\"\u003e\u003cimg src=\"https://github.com/asseco-voice/art/blob/main/evil_logo.png\" width=\"500\"\u003e\u003c/a\u003e\u003c/p\u003e\n\n# Laravel OpenApi generator\n\nThis package provides painless OpenApi YML generation from existing routes. \n\nThe idea is to have as little work to do as possible in order to generate the \nAPI documentation, so the package will try to assume a lot of things such as\nmodels from controller names, request and response parameter based on actual\ntables etc. \n\nFor custom inputs/outputs, options will be provided.\n\n## Installation\n\nInstall the package through composer. It is automatically registered\nas a Laravel service provider.\n\n``composer require asseco-voice/laravel-open-api``\n\n## Usage\n\nRunning the command ``php artisan asseco:open-api`` will generate a new `.yml`\nfile at ``project_root/open-api.yml``.\n\nWhat is covered out-of-the-box:\n\n- read all routes\n- inferring model name from controller name\n- group (tag) them automatically\n- get title and description from \n- generate request and response parameters\n\nFor cases not covered by this convention, refer to [overriding defaults section](#overriding-defaults).\n\nFor additional tweaking, refer to [config](#config).\n\nDepending on number of routes, first run may take a few seconds as it is requesting a DB schema for\neach model it can find. This is cached, so every subsequent run will run much faster. \n\n### Simple out-of-the-box example\n\nGiven the controller:\n\n```\nclass UserController extends Controller\n{\n    /**\n     * Store a newly created resource in storage.    \n     *\n     * Create new User object and store it in DB.\n     */\n    public function store(Request $request): JsonResponse\n    {\n        $user = User::query()-\u003ecreate($request-\u003eall());\n\n        return response()-\u003ejson($user);\n    }\n\n    ...\n```\n\n- command will infer ``User`` as being the main model for the controller\n- title: ``Store a newly created resource in storage.`` \n- description: ``Create new User object and store it in DB.``\n- request data: ``User`` model table attributes without `id`, `created_at`, `updated_at` attributes\n- response data: complete ``User`` model table attributes\n\n## Overriding defaults\n\nCustom cases are handled through controller and method annotations in doc blocks:\n\n```\n/**\n * My controller doc block\n *\n * @annotation random annotation\n */\nclass MyController extends Controller\n{\n    /**\n     * My method doc block\n     *\n     * @annotation another random annotation\n     */\n    public function index()\n    {\n        ...\n    }\n\n   ...\n}\n```\n\n### Groups (tags)\n\nWhen talking about 'groups', we are actually talking about OpenApi 'tags'. \n\nBy default, command will take the controller name, remove ``Controller`` from it\nand split `PascalCase` with spaces (i.e. `SysUserController` results in `Sys User` group name).\n\n- ``@group`` within a controller doc block will override default group. \n- ``@group`` within a method doc block will override default group and controller group\nmaking it an operator with the highest precedence.\n\nIt is possible to stack multiple group annotations.\n\n### Models\n\nModel is used to try to automatically generate inputs and outputs for standard Laravel\nCRUD functions.\n\n**Input (request):** model DB schema with either only fillable properties or except guarded.\nFillable properties have precedence, guarded will be ignored if fillable exists.\n\n**Output (response):** complete model DB schema without hidden fields. \n\nIt is completely valid to have no model associated. In this case, no automatic actions\nwill be performed which require an existing model class.\n\nBy default, model name is extracted from controller name. To change this behavior,\nyou have few options:\n\n- Map a specific controller to a specific model. See [config](#config) for details.\n- Include ``@model`` tag within a controller:\n   - Specifying namespaced model will use that model ``@model My\\Namespaced\\Model`` \n   - Not specifying the namespace will use controller's namespace ``@model Model``\n   \nController tag has higher precedence over configuration mapping. If both exist, and\ncontroller tag fails, configuration will try to fetch the model as well. Failing on\nboth fronts will result in model being ``null``.\n\nIt is possible to exclude part of the model for the request:\n\n- ``@exclude attribute1 attribute2`` is a space separated list of specified model attributes\nwhich will not be included in request data.  \n\n### Path parameters\n\nBy default, path parameter(s) will be set as integer (assuming most of the path parameters are model IDs).\nIn case you want to use UUIDs, this can be changed in ``asseco-open-api`` config file by\nsetting ``service_uses_uuid`` to true.\n\nOverride them by including the following in the method doc block:\n\n- ``@path`` will override what is fetched by default. You must provide it in the following\nconvention ``@path name type description`` where:\n   - ``name`` - parameter name.\n   - ``type`` - [OpenApi data type](https://swagger.io/docs/specification/data-models/data-types/).\n   - ``description`` - text which will be set as parameter description (not required, \n   empty by default, so it can be omitted). \n   \nExamples:\n\n```\n@path name type\n@path name type Some description\n```\n\nIt is not possible to set path parameter ``required`` property. It is automatically set to true because\nOpenApi doesn't support optional path parameters (even though Laravel does).\n\n### Operation ID\n\nBy default, ``operationId`` will be generated for each route, based on the controller/HTTP method\nmapping and the name of the model. If you want to override the default, you can use ``@operationId``\nto provide a different suffix to the operation ID (which will replace what would be an auto-generated model).\n\nPrepended controller/HTTP method will stay intact because of possible conflicts when using update routes\nwhich map to both PUT and PATCH verbs. \n\nExample:\n\n```\n// Provided for an show() method:\n@operationId suffix\n// this will output getSuffix\n\n// Provided for an update() method:\n@operationId suffix\n// this will output putSuffix and patchSuffix\n```\n\n### Request/response parameters\n\nBy default, request/response parameter(s) will be [extracted from model](#models).\n\nOverride them by including ``@request`` or/and `@response` in the method doc block.\n\nExample for ``@request``, working the same for `@response`:\n\n- ``@request`` will override what is fetched by default. You must provide it in the following\nconvention ``@request name type required description`` where:\n   - ``name`` - parameter name.\n   - ``type`` - [OpenApi data type](https://swagger.io/docs/specification/data-models/data-types/).\n   - ``required`` - boolean `true/false` value indicating whether the parameter is required \n   (if omitted, will be set to `true`)\n   - ``description`` - text which will be set as parameter description (if omitted, will be set to\n    empty string)\n   \nExamples:\n\n```\n@request name type\n@request name type true\n@request name type false Some description\n```\n\nFor multiple parameters it is also possible to adopt a different convention:\n\n```\n@request\nname type required description\nname type required description\nname type required description\n```\n\nIn case you want an arbitrary string as a request/response, it can be achieved \nby using double quotes when setting request/response parameters. This way, all \nother parameters will be ignored and only the string inside double quotes will \nbe returned.\n\nExample:\n\n```\n@response \"example\"\n```\n\nYou can include additional input/output models alongside original model with `@requestAppend key Class` or \n`@responseAppend key Class` in your method doc block. This will append given ``Class`` properties on already existing model using the `key` as a key.\n\nI.e. having original model ``User`` (with properties name, email) you want to append `Post` model (with properties\ntitle, description) to it as a list of inputs.\n\n```\n@model User // \u003c-- not needed if it is UserController or you already specified model on the controller\n\n@requestAppend posts Post\n``` \n\nThis will result in following request:\n\n```\n{\n    \"name\": \"string\"\n    \"email\": \"string\"\n    \"posts\": {\n        \"title\": \"string\"\n        \"description\": \"string\"\n    }\n}\n```\n\n#### Response specific\n\nResponses will by default be marked as multiple (indicating collection output, not a single model)\nwhen looking at ``GET`` request without path parameters.\n\n- including ``@multiple true/false`` in the method doc block will override those defaults \n\nIf the variable type is ``array``, you can provide additional property within the parenthesis (be\nsure not to leave blank space between type and parenthesis) to indicate\nof what type are the array values: \n\n```\n@response attribute array[string] true Some description\n```\n\nIt is also possible to directly append a pivot table to the response, even if it \nhas no model associated with it.\n\n```\n@pivot table_name\n```\n\nFor example, if the table was appended to the ``User`` model, the following \nresponse will be returned:\n\n```\n{\n    \"name\": \"string\"\n    \"email\": \"string\"\n    \"pivot\": {\n      \"user_id\": 0\n      \"example_id\": 0\n    }\n}\n```\n\n## Cache\n\nModels database schema is being cached for performance (1d TTL), \nif you modify a migration be sure to run ``php artisan asseco:open-api --bust-cache``\nwhich will force re-caching. \n\n## Config\n\nPublish the configuration with \n``php artisan vendor:publish --provider=\"Asseco\\OpenApi\\OpenApiServiceProvider\"``.\n\nConfiguration requires your minimal engagement, however there are some things which\npackage can't assume. \n\n- For models outside of ``App`` namespace, be sure to include full namespace\nto ``namespaces`` config key as well so that package can automatically get the \nmodel attributes. \n- For controllers not named after their models (in ``ModelController`` format)\nremap in ``controller_model_mapping`` config key.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fasseco-voice%2Flaravel-open-api","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fasseco-voice%2Flaravel-open-api","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fasseco-voice%2Flaravel-open-api/lists"}