{"id":13712375,"url":"https://github.com/swagger-api/swagger-inflector","last_synced_at":"2025-04-08T09:08:47.107Z","repository":{"id":35081297,"uuid":"39236124","full_name":"swagger-api/swagger-inflector","owner":"swagger-api","description":null,"archived":false,"fork":false,"pushed_at":"2024-04-08T07:01:04.000Z","size":41353,"stargazers_count":161,"open_issues_count":42,"forks_count":85,"subscribers_count":24,"default_branch":"master","last_synced_at":"2025-04-01T07:51:21.493Z","etag":null,"topics":["open-source","openapi-specification","openapi3","rest","rest-api","swagger","swagger-api","swagger-inflector","swagger-oss","swagger-specification"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/swagger-api.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":"2015-07-17T05:14:14.000Z","updated_at":"2024-12-11T02:47:03.000Z","dependencies_parsed_at":"2023-11-09T11:56:20.826Z","dependency_job_id":"d3eb3a59-5a4a-4144-92a0-5ccd9f553098","html_url":"https://github.com/swagger-api/swagger-inflector","commit_stats":null,"previous_names":[],"tags_count":43,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/swagger-api%2Fswagger-inflector","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/swagger-api%2Fswagger-inflector/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/swagger-api%2Fswagger-inflector/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/swagger-api%2Fswagger-inflector/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/swagger-api","download_url":"https://codeload.github.com/swagger-api/swagger-inflector/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247809962,"owners_count":20999816,"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":["open-source","openapi-specification","openapi3","rest","rest-api","swagger","swagger-api","swagger-inflector","swagger-oss","swagger-specification"],"created_at":"2024-08-02T23:01:17.769Z","updated_at":"2025-04-08T09:08:47.085Z","avatar_url":"https://github.com/swagger-api.png","language":"Java","readme":"# Swagger Inflector\n\n[![Maven Central](https://maven-badges.herokuapp.com/maven-central/io.swagger/swagger-inflector/badge.svg?style=plastic)](https://maven-badges.herokuapp.com/maven-central/io.swagger/swagger-inflector)\n\n----\n\n**NOTE:** If you're looking for `swagger-inflector` 1.X and Swagger/OpenApi 2.0, please refer to [v1 branch](https://github.com/swagger-api/swagger-inflector/tree/v1)\n\n----\n\nThis project uses the Swagger Specification to drive an API implementation.  Rather than a typical top-down or bottom-up swagger integration, the Inflector uses the swagger specification as a DSL for the REST API.  The spec drives the creation of routes and controllers automatically, matching methods and method signatures from the implementation.  This brings a similar integration approach to the JVM as [swagger-node](https://github.com/swagger-api/swagger-node) brings to the javascript world.\n\nTo allow for an iterative development, the framework will mock responses for any unimplemented methods, based on the specification.  That means you can ship your API to your consumers for review immediately as you build it out.\n\nYou have full control over the mapping of controllers to classes and methods as well as models.\n\n## Quick start!\n\nRun this command to start in a hurry.  It will create a project named `my-project`\n```\ncurl -L https://raw.githubusercontent.com/swagger-api/swagger-inflector/master/setup.sh | project=my-project bash\n```\n\nThis will download everything you need to start editing and running a swagger-inflector based project.  See the output of the command for instructions.\n\n### Components\n\nInflector uses the following libraries:\n\n - swagger models for the swagger definition\n - Jackson for JSON processing\n - Jersey 2.x for REST\n - Minimum Java 8\n\n### Integration\n\nInflector will create routes and add them to Jersey.  You simply need to register the Inflector application in your webapp and it should be compatible with your existing deployment, whether with web.xml, spring, dropwizard, etc.\n\nTo add inflector via `web.xml`:\n\n```xml\n\u003cservlet\u003e\n  \u003cservlet-name\u003eswagger-inflector\u003c/servlet-name\u003e\n  \u003cservlet-class\u003eorg.glassfish.jersey.servlet.ServletContainer\u003c/servlet-class\u003e\n  \u003cinit-param\u003e\n    \u003cparam-name\u003ejavax.ws.rs.Application\u003c/param-name\u003e\n    \u003cparam-value\u003eio.swagger.oas.inflector.OpenAPIInflector\u003c/param-value\u003e\n  \u003c/init-param\u003e\n  \u003cload-on-startup\u003e1\u003c/load-on-startup\u003e\n\u003c/servlet\u003e\n\u003cservlet-mapping\u003e\n  \u003cservlet-name\u003eswagger-inflector\u003c/servlet-name\u003e\n  \u003curl-pattern\u003e/*\u003c/url-pattern\u003e\n\u003c/servlet-mapping\u003e\n```\n\nThis simply adds the `SwaggerInflector` application to Jersey.\n\n### Configuration\n\nInflector uses a single yaml file for configuration.  The default file is `inflector.yaml` but it can be overridden by setting a system property when starting the JVM:\n\n```\n-Dconfig=/path/to/config\n```\n\nThe configuration supports the following:\n\n```yaml\n# mode (development | staging | production).  Default is development, and this value will be overridden by a system property\n# -Denvironment=production for example\nenvironment: development\n\n# configure your default controller package for method discovery\ncontrollerPackage: io.swagger.oas.sample.controllers\n\n# configure the default model package for model discovery\nmodelPackage: io.swagger.oas.sample.models\n\n# the path to the swagger definition (Note! this can be overridden with -DswaggerUrl as a system property\nswaggerUrl: openapi.yaml\n\n# specific mappings for models, used to locate models in the `#/definitions/${model}`\nmodelMappings:\n  User: io.swagger.oas.sample.models.User\n\n# HTTP response code when required parameters are missing\ninvalidRequestCode: 400\n\n#Allows to configure the exposed spec (values in example are the defaults)\nexposedSpecOptions:\n  parseOptions:\n    resolve: false\n    resolveFully: false\n  useOriginalNotParsed: false\n  hideInflectorExtensions: true\n  mergeRootPath: true\n\n```\n\n### Locating the controller class\n\nThe actual controller class for each method is located via the first of the following mechanisms:\n- a x-swagger-router-controller extension at the method level can specify the specific controller class\n- each tag associated with the method is assembled into the classnames \"\u0026lt;controllerPackage\u0026gt;.\u0026lt;Tag\u0026gt;\" or \n\"\u0026lt;controllerPackage\u0026gt;.\u0026lt;Tag\u0026gt;Controller\", the first of these classes that is found by Class.forName(...) will be used\n- an optional \u0026lt;controllerClass\u0026gt; configuration parameter is appended to \u0026lt;controllerPackage\u0026gt; \n- as a last resort a class named \u0026lt;controllerPackage\u0026gt;.Default is used\n\nBy default the class is loaded directly with Class.forName(...).newInstance() - but you can override class creation\nby providing a custom ControllerFactory to the inflector configuration (for example if you want your controllers to be \nloaded by a DI framework).\n\n### Locating the target method\n\nWhen locating methods, the `operationId` is used as the method name for lookup via reflection.  If not specified, there is logic for generation of a method name.\n\nOnce a method is matched via name, the parameter types will be compared to ensure we have the right model.  In all methods, only java objects are supported--primitives currently will not match (this allows for proper nulls).\n\nYou can override a model mapping by setting a vendor extension in the swagger yaml:\n\n```yaml\n# uses method name, look for controllerPackage in the configuration\npaths:\n  /test1:\n    get:\n      x-swagger-router-controller: SampleController\n      operationId: getTest1\n      parameters:\n        - name: name\n          in: query\n          type: string\n      responses:\n        200:\n          description: Success!\n```\n\nFrom the configuration example above, this will look for the following class:\n\n```\nclass: io.swagger.sample.controllers.SampleController\n```\n\nwith the following method:\n\n```\nmethod: public Object getTest1(\n    RequestContext,\n    java.lang.String name)\n```\n\n#### Complex inputs\n\nWhen there are complex inputs, such as the example below:\n\n```yaml\npaths:\n  /test2:\n    post:\n      x-swagger-router-controller: SampleController\n      operationId: addUser\n      requestBody:\n          content:\n            \"application/json\":\n              schema:\n                $ref: '#/definitions/User'\n      parameters:\n        - name: name\n          in: query\n          type: string\n      responses:\n        200:\n          description: Success!\n```\n\nthe Inflector will do the following:\n\n - Look in vendor extensions for the models to see if a mapping exists.  If so, it will attempt to load it via the classloader\n\n ```yaml\n   Address:\n    x-swagger-router-model: io.swagger.test.models.Address\n    properties:\n      street:\n        type: string\n        example: 12345 El Monte Road\n      city:\n        type: string\n        example: Los Altos Hills\n      state:\n        type: string\n        example: CA\n      zip:\n        type: string\n        example: '94022'\n ```\n\n - Look in the configuration for a mapping between `User` and a concrete class definition.  If the definition exists AND the class can be loaded, the method will look like such:\n\n ```\n public ResponseContext addUser (\n    RequestContext context,             // request context\n    io.swagger.sample.models.User user, // user being added\n    java.lang.String name)              // the `name` query param\n ```\n\n - If the definition does not exist, the `modelPackage` from the configuration will be used to attempt to load the class:\n\n ```\n\n\n ```\n\n If the definition can be loaded it will be used as the method signature\n\n - If no model can be loaded, it is the developer's job to unwrap the input and parse it on their own.  This requires `Content-Type`-specific processing.  Inflector will then look for the following method:\n\n ```\n public ResponseContext addUser (\n    RequestContext context,             // request context\n    JsonNode user,                      // a Json tree representing the user\n    java.lang.String name)              // the `name` query param\n ```\n\n - If no method can be found, a mock response will be returned based on the swagger definition.  For complex objects, if an `example` exists, we will use that.  Otherwise, it will be constructed.\n\n\nThe RequestWrapper and ResponseContext contain information about headers (in and outbound), content-type and acceptable response types.\n\n#### Outputs\n\nYour controllers can return null (void response), an object (entity), or a `ResponseContext`, which allows you to send specific error codes, headers, and an optional entity.\n\nFor example, if you want to return a `Pet` from a controller:\n\n```java\n    public ResponseContext getPet(RequestContext request, java.lang.Integer petId) {\n        // do your magic to fetch a pet...\n        Pet pet = complexBusinessLogic.getPetById(petId);\n\n        return new ResponseContext()\n                .status(Status.OK)\n                .entity(pet);\n    }\n```\n\nand the Inflector will return a `200` response code, marshalling the `Pet` object into the appropriate content type.\n\nIf you do not implement your controller, the Inflector will generate sample data based on your model definitions.  It will honor any examples that you have in the definitions, assuming they are compatible with the schema you declared.  For example, this definition:\n\n```yaml\nproperties:\n  street:\n    type: \"string\"\n    example: \"12345 El Monte Blvd\"\n  city:\n    type: \"string\"\n    example: \"Los Altos Hills\"\n  state:\n    type: \"string\"\n    example: \"CA\"\n    minLength: 2\n    maxLength: 2\n  zip:\n    type: \"string\"\n    example: \"94022\"\nxml:\n  name: \"address\"\n```\n\nWill produce this example for a `Accept:application/json`:\n\n```json\n{\n  \"street\" : \"12345 El Monte Blvd\",\n  \"city\" : \"Los Altos Hills\",\n  \"state\" : \"CA\",\n  \"zip\" : \"94022\"\n}\n```\n\nand `application/yaml`:\n\n```yaml\nstreet: \"12345 El Monte Blvd\"\ncity: \"Los Altos Hills\"\nstate: \"CA\"\nzip: \"94022\"\n```\n\nand `application/xml`:\n\n```xml\n\u003caddress\u003e\n  \u003cstreet\u003e12345 El Monte Blvd\u003c/street\u003e\n  \u003ccity\u003eLos Altos Hills\u003c/city\u003e\n  \u003cstate\u003eCA\u003c/state\u003e\n  \u003czip\u003e94022\u003c/zip\u003e\n\u003c/address\u003e\n```\n\n#### Payload validation\n\nSince your inbound and outbound payloads are defined with the Swagger schema, Inflector \ncan validate them at runtime.  Just enable payload validations in your inflector config:\n\n```yaml\nvalidatePayloads: true\n```\n\nAnd at start-up, Inflector will read the schema and attach the relevant section of it \nto the operation.  For example, a post operation that has this as the schema definition:\n\n```json\n{\n  \"Category\": {\n    \"required\": [\n      \"id\"\n    ],\n    \"properties\": {\n      \"id\": {\n        \"type\": \"integer\",\n        \"format\": \"int64\"\n      },\n      \"name\": {\n        \"type\": \"string\"\n      }\n    },\n    \"xml\": {\n      \"name\": \"Category\"\n    }\n  }\n}\n```\n\nWill fail if the incoming body looks like this:\n\n```json\n{\n  \"name\": \"Tony\"\n}\n```\nbecause the required field `id` is missing.\n\nThe same goes for responses generated by the server.  Any response code that you send will \nbe validated against it's corresponding schema.\n\nYou can choose to enable this in development,\nstaging, or production.\n\n#### Content type negotiation\n\nThere is a pluggable framework for handling different content types.  You can register any processor by the following:\n\n```java\nEntityProcessor myProcessor = new MyEntityProcessor();  // implements EntityProcessor\nEntityProcessorFactory.addProcessor(myProcessor);\n```\n\n#### Development Lifecycle\n\nThere are three modes that the Inflector supports, as configured by the `environment` attribute in the inflector config:\n\n - **development**.  In this mode, mock responses will be sent for controllers which are not implemented.  The intention\n   is to allow you to quickly iterate on the implementation of the design.  In addition, missing model implementations\n   are tolerated and supported.\n\n - **staging**.  Warning messages will be logged when starting the service for any missing controller, method, or model.\n\n - **production**.  The expectation is all methods and declared (manually mapped) models exist.  If they don't, it'll throw\n   nasty errors and the server will not start.\n\nIn development mode, there is a `/debug.json` page which shows implementation details of the inflector service.\n\nIf your Swagger Description is unparsable, the server will throw ugly errors on startup and the `debug.json` page will\n   give indications as to why.\n\n#### Samples\nThe samples are a being refactor to support the new inflector.\n\nYou will soon find samples for the inflector project in the [Swagger-Samples](https://github.com/swagger-api/swagger-samples) repository.  The inflector projects start with `inflector-`\n\n#### Running tests\n\nIf running Java 8, you will need to run a variant that has backported fix 8157236. Azul Zulu is confirmed to work (https://github.com/jmockit/jmockit1/issues/710).\n\nIf running with Java 9 or later, you will need to either:\n- Pass `-Djdk.attach.allowAttachSelf=true` to the VM.\n- Configure the test execution JVM to start with the \"-javaagent:\u003cproper path\u003e/jmockit.1.x.jar\" initialization parameter. It can be specified in the build script file for tools such as Maven or Gradle, or in a \"Run/Debug Configuration\" for IntelliJ IDEA or Eclipse.\n\n## Security contact\n\nPlease disclose any security-related issues or vulnerabilities by emailing [security@swagger.io](mailto:security@swagger.io), instead of using the public issue tracker.\n","funding_links":[],"categories":["By Product"],"sub_categories":["Swagger"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fswagger-api%2Fswagger-inflector","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fswagger-api%2Fswagger-inflector","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fswagger-api%2Fswagger-inflector/lists"}