{"id":15091393,"url":"https://github.com/getyourguide/openapi-validation-java","last_synced_at":"2025-04-12T06:31:21.074Z","repository":{"id":169434862,"uuid":"639785490","full_name":"getyourguide/openapi-validation-java","owner":"getyourguide","description":"Build trust in your spec by validating live requests and responses against your OpenAPI spec.","archived":false,"fork":false,"pushed_at":"2025-04-11T09:14:02.000Z","size":419,"stargazers_count":9,"open_issues_count":4,"forks_count":1,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-04-11T11:40:01.530Z","etag":null,"topics":["java","openapi","openapi-specification","openapi-validation","spring-boot"],"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/getyourguide.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":"CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-05-12T08:14:30.000Z","updated_at":"2025-04-11T09:14:05.000Z","dependencies_parsed_at":"2023-09-23T01:12:36.960Z","dependency_job_id":"0cae6714-87d4-4ce4-8a8e-ecd6bd63ad5e","html_url":"https://github.com/getyourguide/openapi-validation-java","commit_stats":{"total_commits":119,"total_committers":3,"mean_commits":"39.666666666666664","dds":0.4453781512605042,"last_synced_commit":"5b6ffed2b882ec71c0c8312783bf11c8a16e4309"},"previous_names":["getyourguide/openapi-validation-java"],"tags_count":20,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/getyourguide%2Fopenapi-validation-java","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/getyourguide%2Fopenapi-validation-java/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/getyourguide%2Fopenapi-validation-java/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/getyourguide%2Fopenapi-validation-java/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/getyourguide","download_url":"https://codeload.github.com/getyourguide/openapi-validation-java/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248529491,"owners_count":21119520,"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":["java","openapi","openapi-specification","openapi-validation","spring-boot"],"created_at":"2024-09-25T10:40:48.247Z","updated_at":"2025-04-12T06:31:16.024Z","avatar_url":"https://github.com/getyourguide.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![GHA check status](https://github.com/getyourguide/openapi-validation-java/actions/workflows/check.yml/badge.svg)](https://github.com/getyourguide/openapi-validation-java/actions?query=branch%3Amain)\n\n# Java OpenAPI Validation Library\n\nBuild trust in your spec by validating live requests and responses against your OpenAPI spec.\nGet informed through logs or metrics when violations occur.\n\nUses the following library for the validation: https://bitbucket.org/atlassian/swagger-request-validator\n\n## Installation\n\n1. [Add dependency in gradle](#gradle)\n2. [Provide OpenAPI specification file](#provide-openapi-specification-file)\n\n### Gradle\n#### Spring 3\nThere are separate integrations for `spring-boot-starter-web` (servlet) and `spring-boot-starter-webflux` (reactive).\n\n##### spring-boot-starter-web (servlet)\n```groovy\ndependencies {\n    implementation \"com.getyourguide.openapi.validation:spring-boot-starter-web:{latest-version}\"\n}\n```\n\n##### spring-boot-starter-webflux (reactive)\n```groovy\ndependencies {\n    implementation \"com.getyourguide.openapi.validation:spring-boot-starter-webflux:{latest-version}\"\n}\n```\n\n### Provide OpenAPI specification file\nThe library will require a valid OpenAPI specification file to be present in the classpath.\n\nBy default, it will look for `openapi.yaml`, `openapi.json`, `spec.yaml` or `spec.json`.\n\nDo one of the following.\n- Copy spec into `src/main/resources`\n- Generate a single spec file that you add to `src/main/resources`\n\n### Copy spec into `src/main/resources`\nCopy all the spec files to `src/main/resources` and make sure that the main file has a correct name as mentioned\nabove. This can be done as part of the CI pipeline.\n\n### Generate a single spec file\nUse [openapi-generator](https://github.com/OpenAPITools/openapi-generator) to generate a single\n`openapi.yaml` or `openapi.json` file and add that to `src/main/resources`.\nSee [openapi-generator Installation](https://github.com/OpenAPITools/openapi-generator#1---installation) for more\ninformation on how to use it with various methods (artifact, docker, brew, npm, ...).\n\nOne example for installing openapi-generator with brew and generating a single spec file:\n\n```shell\nbrew install openapi-generator\nopenapi-generator generate -g openapi -i spec/index.yaml -o /tmp/openapi-spec/\ncp /tmp/openapi-spec/openapi.json src/main/resources/openapi.json\n```\nPlease **adjust** the commands to fit your **folder structure**.\n\n## Configuration\n\nWithout any configuration the library will\n- Search for specification file of name (`openapi.yaml/json` or `spec.yaml/json`) in resources\n- Validate 0.1% of all requests\n\n### application.properties\nThe following configuration can be done within the `application.properties`.\n\n```properties\n# Control the percentage of requests that are validated. The default is 0.1% of traffic.\n# Here set to validate 100% of traffic\nopenapi.validation.sample-rate=1.0\n\n# Custom location of specification file within resources or filesystem.\nopenapi.validation.specification-file-path=/tmp/openapi-spec/openapi.json\n# If it is within src/main/resources/folder/my-spec.json use\nopenapi.validation.specification-file-path=folder/my-spec.json\n\n# Custom log level for violations (ignore, info, warn, error)\n# Default: info\nopenapi.validation.violation-log-level=error\n\n# Comma separated list of paths to be excluded from validation. Default is no excluded paths\nopenapi.validation.excluded-paths=/_readiness,/_liveness,/_metrics\n# Allows to exclude requests based on headers. Default is no excluded headers.\n# Each entry is the header plus a matching regex. The regex is case insensitive.\nopenapi.validation.excluded-headers[0]=User-Agent: .*(bingbot|googlebot).*\n\n# Throttle the validation reporting (logs \u0026 metrics) to a maximum of 1 log/metric per 10 seconds.\n# Default is null which results in no throttling.\nopenapi.validation.validation-report-throttle-wait-seconds=10\n\n# Throttle the validation reporting (logs \u0026 metrics) to a maximum of 1 log/metric per 10 seconds.\n# Default is \"openapi.validation\".\nopenapi.validation.validation-report-metric-name=validation.openapi\n\n# Add additional tags to be logged with metrics. They should be in the format {KEY}={VALUE},{KEY}={VALUE}\n# Default is no additional tags.\nopenapi.validation.validation-report-metric-additional-tags=service=example,team=chk\n\n# Fail requests on request/response violations. Defaults to false.\nopenapi.validation.should-fail-on-request-violation=true\nopenapi.validation.should-fail-on-response-violation=true\n```\n\n### DataDog metrics\nTo use DataDog metrics, you need to add the following dependency to your `build.gradle`:\n\n```groovy\ndependencies {\n    implementation \"com.getyourguide.openapi.validation:metrics-reporter-datadog-spring-boot:{latest-version}\"\n}\n```\n\nBy default, the existing `StatsDClient` bean will be used to log metrics.\nIf that bean doesn't exist it will not log any metrics.\n\nIt is possible to configure the `StatsDClient` to be used with the following properties:\n\n```properties\nopenapi.validation.datadog.statsd.service.host=localhost\nopenapi.validation.datadog.statsd.service.port=8125\n```\n\n### Logging\n#### LoggingContext\n```java\n@Component\npublic class ExampleLoggerExtension implements LoggerExtension {\n    @Override\n    public Closeable addToLoggingContext(@NonNull Map\u003cString, String\u003e newTags) {\n        return LoggingContext.putAll(newTags);\n    }\n}\n```\n\n#### Custom Logging\n```java\n@Slf4j\n@Component\npublic class CustomViolationLogger implements ViolationLogger {\n  @Override\n  public void log(OpenApiViolation violation) {\n    log.error(\"!!! Spec Violation on {}\", violation.getRequestMetaData().getUri());\n  }\n}\n```\n\n### Custom traffic selection\nDefine which traffic should be validated. This can be used to only include specific traffic or\nto enable validation based on a feature flag or experiment. \n```java\n@Component\npublic class SampleRateTrafficSelector implements TrafficSelector {\n\n    private final FeatureFlag featureFlags;\n    \n    public SampleRateTrafficSelector(FeatureFlags featureFlags) {\n        this.featureFlags = featureFlags;\n    }\n    \n    @Override\n    public boolean shouldRequestBeValidated(RequestMetaData requestMetaData) {\n        return featureFlags.isEnabled(\"MY_FEATURE_FLAG\");\n    }\n}\n```\n\n### Custom log levels\nOne can customize log levels as per the following example. The default log level is `info`.\n\nThe key to be used here is also printed in the violation log message.\n\n```java\n@Configuration\npublic class ValidatorConfiguration {\n    @Bean\n    public ValidatorConfiguration buildValidatorConfiguration() {\n        return new ValidatorConfigurationBuilder()\n            .levelResolverLevel(\"validation.request.body.schema.additionalProperties\", LogLevel.ERROR)\n            .levelResolverDefaultLevel(LogLevel.INFO)\n            .build();\n    }\n}\n```\n\n### Multiple spec files\nIt is possible to use multiple spec files for different paths. This can be achieved as demonstrated in the following\ncode snipped.\n\nIt is best practice to use a catch-all spec file. If a request is not matching any of the paths defined here it will\nresult in a violation error with log level `warn`. \n\n```java\n@Configuration\npublic class OpenApiValidatorConfiguration {\n    @Bean\n    public ValidatorConfiguration buildValidatorConfiguration() {\n        return new ValidatorConfigurationBuilder()\n            .specificationPath(Pattern.compile(\"/v1/.*\"), \"openapi-v1.yaml\")\n            .specificationPath(Pattern.compile(\"/.*\"), \"openapi.yaml\")\n            .build();\n    }\n}\n```\n\n### Exclude certain violations\nCertain violations can get excluded from reporting. This can be achieved as demonstrated in the following snippet.\n\n**Note:** Only use this where it is really needed. It is best practice to fix the actual violations by either adjusting\nthe specification, the server implementation, or the client sending wrong requests.\n\n```java\n@Component\npublic class ViolationExclusionsExample implements ViolationExclusions {\n  @Override\n  public boolean isExcluded(OpenApiViolation violation) {\n    return violation.getDirection().equals(Direction.REQUEST)\n            \u0026\u0026 violation.getMessage().equals(\"[Path '/name'] Instance type (integer) does not match any allowed primitive type (allowed: [\\\"string\\\"])\");\n  }\n}\n```\n\n### Provide metric tags at runtime\nSometimes you want to generate your own metric tags based on the violation.\nThis can be achieved as demonstrated in the following snippet.\n\n```java\n@Component\npublic class MetricTagProviderExample implements MetricTagProvider {\n  @Override\n  public List\u003cMetricTag\u003e getTagsForViolation(OpenApiViolation violation) {\n    return List.of(new MetricTag(\"rule\", violation.getRule()));\n  }\n}\n```\n\n## Examples\nRun examples with `./gradlew :examples:example-spring-boot-starter-web:bootRun` or `./gradlew :examples:example-spring-boot-starter-webflux:bootRun`.\n\n## Current known limitations\nThese are current known limitations of the library.\nAny help on resolving these is appreciated. PRs are always welcome.\n\n- Only supports Content-Type JSON/XML/HTML\n  - In order to avoid accidentally caching bigger resources (videos, streams, ...)\n- Ignores the error `Instance failed to match exactly one schema (matched X out of Y)`\n  - This is currently on purpose, but should be configurable\n- Error responses can't (yet) be validated in webflux/reactive\n\n## Versioning\n\nThe library is following [Semantic Versioning](https://semver.org/).\n\n### Dependency updates\nSince most of the updates to the library are dependency updates, we also follow their semver changes as well.\nAs there will be (most probably) a multiple dependencies updated with a version we release, we always consider\nthe \"highest\" version bump (from semver perspective) as the decisioning factor.\n\n- A `major` version of this library indicates at least one of the dependencies has had a `major` release.\n- Similarly, a `minor` version bump indicates that there was no `major` dependency update, only `minor` ones.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgetyourguide%2Fopenapi-validation-java","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgetyourguide%2Fopenapi-validation-java","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgetyourguide%2Fopenapi-validation-java/lists"}