- Fix support for discriminator in response body validation (#285)
- Replace bundled json_refs fork with own code
- Fix issue with non file downloads / JSON responses #281
- Added
OpenapiFirst::Definition#[]
to access the raw Hash representation of the OAS document. Example:api['components'].fetch('schemas', 'Stations')
- Fix issue with parsing reponse body when using Rails #281
-
Fix
OpenapiFirst::Test.register
#276 -
Request validation middleware now accepts
error_response: false
do disable rendering a response. This is useful if you just want to collect metrics (via hooks) during a migration phase.
- Fix setting custom error response (thanks @gobijan)
-
Test Assertions! 📋 You can now use
assert_api_conform
for contract testing in your rack-test / Rails integration tests. See Readme for details. -
New option for
Middlewares::ResponseValidation
::raise_error
(default: true). If set tofalse
, the middleware will not aise an error if the response is invalid. 🤫 -
Hooks 🪝🪝 (see Readme for details). You can use these to collect metrics, write error logs etc.:
after_request_validation
after_response_validation
after_request_body_property_validation
after_request_parameter_property_validation
-
Exceptions such as
OpenapiFirst::ResponseInvalidError
not respond to#request
to get information about the validated request 💁🏻 -
Performance improvements 🚴🏻♀️
-
Validation failures returned by
ValidatedRequest#error
always returns a#message
. So you can callmy_validated_request.error.message if validated_request.invalid?
and always get a human-readable error message. 😴
Definition#request.validate
was removed. Please useDefinition#validate_request
instead.Definition#validate_request
returns aValidatedRequest
which delgates all methods to the original (rack) request, except for#valid?
#parsed_body
.#parsed_query
,#operation
etc. See Readme for details.- The
Operation
class was removed.ValidatedRequest#operation
now returns the OpenAPI 3 operation object as a plain Hash. So you can still callValidatedRequest#operation['x-foo']
. You can callValidatedRequest#operation_id
if you just need the operationId.
-
Definition#operations
has been removed. Please useDefinition#routes
, which returns a list of routes. Routes have a#path
,#request_method
,#requests
and#responses
. A route has one path and one request method, but can have multiple requests (one for each supported content-type) and responses (statuses + content-type). -
Several internal changes to make the code more maintainable, more performant , support hooks and prepare for OpenAPI 4. If you have monkey-patched OpenapiFirst, you might need to adjust your code. Please contact me if you need help.
ValidationError#error
,#instance_location
and#schema_location
have been deprecated. UseValidationError#message
,#data_pointer
and#schema_pointer
instead.Failure#error_type
has been deprecated. Use#type
instead
- Allow using json_schemer 2...3
- Fix Rack 2 compatibility
- Fixed: Don't call deprecated methods in middlewares
Some redundant methods to validate or inspect requests/responses will be removed in 2.0. So this release deprecates these methods.
- Deprecate
OpenapiFirst::RuntimeRequest#validate
,#validate!
,#validate_response
,#response
. UseOpenapiFirst.load('openapi.yaml').validate_request(rack_request, raise_error: true/false)
instead - Deprecate
OpenapiFirst::RuntimeResponse#validate
. UseOpenapiFirst.load('openapi.yaml').validate_response(rack_request, rack_response, raise_error: true/false)
instead.
- Fixed Rack 2 / Rails 6 compatibility (#246
- Added support for
/some/{kebab-cased}
path parameters (#245)
- Fixed handling "binary" format in optional multipart file uploads
- Cache the resolved OAD. This especially makes things run faster in tests.
- Internally used
Operation#query_parameters
,Operation#path_parameters
etc. now only returns parameters that are defined on the operation level not on the PathItem. UsePathItem#query_parameters
to get those.
- The response definition is found even if the status is defined as an Integer instead of a String. This is not provided for in the OAS specification, but is often done this way, because of YAML.
- Reduced initial load time for composed API descriptions #232
- Chore: Add Readme back to gem. Add link to docs.
- Fixed warning about duplicated constant
No breaking changes
New features:
- Added new API:
Definition#validate_request
,Definition#validate_response
,RuntimeRequest#validate_response
(see readme) #222
Fixes:
- Manual response validation (without the middleware) just works in Rails' request tests now. #224
No breaking changes
- Added
OpenapiFirst.parse(hash)
to load ("parse") a resolved/de-referenced Hash - Added support for unescaped special characters in the path params (#217)
- Added
operation
toRuntimeRequest
by @MrBananaLord
- Fix reading response body for example when running Rails (
ActionDispatch::Response::RackBody
) - Add
known?
,status
,body
,headers
,content_type
methods to inspect the parsed response (RuntimeResponse
) - Add
OpenapiFirst::ParseError
which is raised by low-level interfaces likerequest.body
if the body could not be parsed. - Add "code" field to errors in JSON:API error response
- Breaking: The default error uses application/problem+json content-type
- Breaking: Moved rack middlewares to OpenapiFirst::Middlewares
- Breaking: Rename OpenapiFirst::ResponseInvalid to OpenapiFirst::ResponseInvalidError
- Breaking: Remove OpenapiFirst::Router
- Breaking: Remove
env[OpenapiFirst::OPERATION]
. Useenv[OpenapiFirst::REQUEST]
instead. - Breaking: Remove
env[OpenapiFirst::REQUEST_BODY]
,env[OpenapiFirst::PARAMS]
. Useenv[OpenapiFirst::REQUEST].body env[OpenapiFirst::REQUEST].params
instead. - Add interface to validate requests / responses without middlewares (see "Manual validation" in README)
- Add OpenapiFirst.configure
- Add OpenapiFirst.register, OpenapiFirst.plugin
- Fix response header validation with Rack 3
- Fixed: Add support for paths like
/{a}..{b}
- Fix: Make response header validation work with rack 3
- Refactor router
- Remove dependency hanami-router
- PathItem and Operation for a request can be found by calling methods on the Definitnion
- Fixed #155
- Breaking / Regression: A paths like /pets/{from}-{to} if there is a path "/pets/{id}"
- Added:
OpenapiFirst::Config.default_options=
to set default options globally - Added: You can define custom error responses by subclassing
OpenapiFirst::ErrorResponse
and register it viaOpenapiFirst.register_error_response(name, MyCustomErrorResponse)
- Update json_schemer to version 2.0
- Breaking: Requires Ruby 3.1 or later
- Added: Parameters are available at
env[OpenapiFirst::PATH_PARAMS]
,env[OpenapiFirst::QUERY_PARAMS]
,env[OpenapiFirst::HEADER_PARAMS]
,env[OpenapiFirst::COOKIE_PARAMS]
in case you need to access them separately. Merged path and query parameters are still available atenv[OpenapiFirst::PARAMS]
- Breaking / Added: ResponseValidation now validates response headers
- Breaking / Added: RequestValidation now validates cookie, path and header parameters
- Breaking: multipart File uploads are now read and then validated
- Breaking: Remove OpenapiFirst.env method
- Breaking: Request validation returns 400 instead of 415 if request body is required, but empty
- Remove obsolete dependency: deep_merge
- Remove obsolete dependency: hanami-utils
- Fixed dependencies. Remove unused code.
- Removed:
OpenapiFirst::Responder
andOpenapiFirst::RackResponder
- Removed:
OpenapiFirst.app
andOpenapiFirst.middleware
- Removed:
OpenapiFirst::Coverage
- Breaking: Parsed query and path parameters are available at
env[OpenapiFirst::PARAMS]
(orenv['openapi.params']
) instead ofOpenapiFirst::PARAMETERS
. - Breaking: Request body and parameters now use string keys instead of symbols!
- Breaking: Query parameters are now parsed exactly like in the API description via the openapi_parameters gem. This means a couple of things:
- Query parameters now support
explode: true
(default) andexplode: false
for array and object parameters. - Query parameters with brackets like 'filter[tag]' are no longer deconstructed into nested hashes, but accessible via the
filter[tag]
key. - Query parameters are no longer interpreted as
style: deepObject
by default. If you want to usestyle: deepObject
, for example to pass a nested hash as a query parameter likefilter[tag]
, you have to setstyle: deepObject
explicitly.
- Query parameters now support
- Path parameters are now parsed exactly as in the API description via the openapi_parameters gem.
- Fix: Query parameter validation does not fail if header parameters are defined (Thanks to JF Lalonde)
- Update Ruby dependency to >= 3.0.5
- Handle simple form-data in request bodies (see #149)
- Update to hanami-router 2.0.0 stable
- You can pass a filepath to
spec:
now so you no longer have to callOpenapiFirst.load
anymore. - Router is optional now.
You no longer have to add
Router
to your middleware stack. You still can add it to customize behaviour by setting options, but you no longer have to add it. If you don't add the Router, make sure you passspec:
to your request/response validation middleware. - Support "4xx" and "4XX" response definitions. (4XX is defined in the standard, but 2xx is used in the wild as well 🦁.)
- Removed warning about missing operationId, because operationId is not used until the Responder is used.
- Raise HandlerNotFoundError when handler cannot be found
-
Add
RackResponder
-
BREAKING CHANGE: Handler classes are now instantiated only once without any arguments and the same instance is called on each following call/request.
Yanked. No useful changes.
- BREAKING CHANGE: Use a Hash instead of named arguments for middleware options for better compatibility Using named arguments is actually not supported in Rack.
- Pin hanami-router version, because alpha6 is broken.
- Support status code wildcards like "2XX", "4XX"
- Populate default parameter values
- Use json_refs to resolve OpenAPI file. This removes oas_parser and ActiveSupport from list of dependencies
- Empty query parameters are parsed and request validation returns 400 if an empty string is not allowed. Note that this does not look at
allowEmptyValue
in any way, because allowEmptyValue is deprecated.
- Fix: Don't mix path- and operation-level parameters for request validation
- Handle custom x-handler field in the API description to find a handler method not based on operationId
- Add
resolver
option to provide a custom resolver to find a handler method
- Better error message if string does not match format
- readOnly and writeOnly just works when used inside allOf
- Return indicator (
source: { parameter: 'list/1' }
) in error response body when array item in query parameter is invalid
- Add support for arrays in query parameters (style: form, explode: false)
- Remove warning when handler is not implemented
- Add
not_found: :continue
option to Router to make it do nothing if request is unknown
- content-type is found while ignoring additional content-type parameters (
application/json
is found when request/response content-type isapplication/json; charset=UTF8
) - Support wildcard mime-types when finding the content-type
- Add
response_validation:
,router_raise_error
options to standalone mode.
- Allow response to have no media type object specified
- Fix response when handler returns 404 or 405
- Don't validate the response content if status is 204 (no content)
- Change
ResponseValidator
to raise an exception if it found a problem - Params have symbolized keys now
- Remove
not_found
option from Router. Return 405 if HTTP verb is not allowed (via Hanami::Router) - Add
raise_error
option to OpenapiFirst.app (false by default) - Add ResponseValidation to OpenapiFirst.app if raise_error option is true
- Rename
raise
option toraise_error
- Add
raise_error
option to RequestValidation middleware - Raise error if handler could not be found by Responder
- Add
Operation#name
that returns a human readable name for an operation
- Raise error if you forgot to add the Router middleware
- Make OpenapiFirst.app raise an error in test env when request path is not specified
- Rename OperationResolver to Responder
- Add ResponseValidation middleware that validates the response body
- Add
raise
option to Router middleware to raise an error if request could not be found in the API description similar to committee's raise option. - Move namespace option from Router to OperationResolver
- Return 400 if request body has invalid JSON (issue) thanks Thomas Frütel
- Fix duplicated key in
required
when generating JSON schema forsome[thing]
parameters
- Add support for query parameters named
"some[thing]"
(issue)
- Make request validation usable standalone
- Add merged parameter and request body available to env at
env[OpenapiFirst::INBOX]
in request validation - Path and query parameters with
type: boolean
now get converted totrue
/false
- Rename
OpenapiFirst::PARAMS
toOpenapiFirst::PARAMETERS
- Add missing
require
to work with new version ofoas_parser
- Make use of hanami-router, because it's fast
- Remove option
allow_unknown_query_paramerters
- Move the namespace option to Router
- Convert numeric path and query parameters to
Integer
orFloat
- Pass the Rack env if your action class' initializers accepts an argument
- Respec rack's
env['SCRIPT_NAME']
in router - Add MIT license
- Bugfix: params.env['unknown'] now returns
nil
as expected. Thanks @tristandruyen.
- Removed radix tree, because of a bug (namusyaka/r2ree-ruby#2)
- Performance: About 25% performance increase (i/s) with help of c++ based radix-tree and some optimizations
- Update dependencies
- Fix: version number of oas_parser
- Remove warnings for Ruby 2.7
- Merge QueryParameterValidation and ReqestBodyValidation middlewares into RequestValidation
- Rename option to
allow_unknown_query_paramerters
- Fix: Rewind request body after reading
- Add option to parse only certain paths from OAS file
- Add support to map operationIds like
things#index
orweb.things_index
- Make ResponseValidator errors easier to read
- Set the content-type based on the OpenAPI description #29
- Add CHANGELOG 📝