Skip to content

Commit 91f03a3

Browse files
committed
Add usage of feature #345 to README
1 parent cbb3f7d commit 91f03a3

1 file changed

Lines changed: 78 additions & 0 deletions

File tree

README.md

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ You can use openapi_first on production for [request validation](#request-valida
1919
- [Configuration](#configuration)
2020
- [Hooks](#hooks)
2121
- [Alternatives](#alternatives)
22+
- [Frequently Asked Questions](#frequently-asked-questions)
23+
- [How can I adapt request paths that don't match my schema?](#how-can-i-adapt-request-paths-that-dont-match-my-schema)
2224
- [Development](#development)
2325
- [Benchmarks](#benchmarks)
2426
- [Contributing](#contributing)
@@ -327,6 +329,82 @@ That aside, closer integration with specific frameworks like Sinatra, Hanami, Ro
327329
This gem was inspired by [committee](https://github.com/interagent/committee) (Ruby) and [Connexion](https://github.com/spec-first/connexion) (Python).
328330
Here is a [feature comparison between openapi_first and committee](https://gist.github.com/ahx/1538c31f0652f459861713b5259e366a).
329331

332+
## Frequently Asked Questions
333+
334+
### How can I adapt request paths that don't match my schema?
335+
336+
If your API is deployed at a different path than what's defined in your OpenAPI schema, you can use `env[OpenapiFirst::PATH]` to override the path used for schema matching.
337+
338+
Let's say you have `openapi.yaml` like this:
339+
340+
```yaml
341+
servers:
342+
- url: https://yourhost/api
343+
paths:
344+
# The actual endpoint URL is https://yourhost/api/resource
345+
/resource:
346+
```
347+
348+
Here your OpenAPI schema defines endpoints starting with `/resource` but your actual application is mounted at `/api/resource`. You can bridge the gap by creating a custom middleware:
349+
350+
```ruby
351+
class CustomOpenAPIValidation < OpenapiFirst::Middlewares::RequestValidation
352+
def call(env)
353+
request = Rack::Request.new(env)
354+
355+
# Strip the "/api" prefix for schema matching
356+
env[OpenapiFirst::PATH] = request.path.to_s.sub(%r"^/api", "")
357+
358+
super
359+
end
360+
end
361+
362+
# Add your custom middleware
363+
use CustomOpenAPIValidation, 'openapi.yaml'
364+
365+
# You can add ResponseValidation without any customization.
366+
use OpenapiFirst::Middlewares::ResponseValidation, 'openapi.yaml'
367+
```
368+
369+
In this case, you might want to serve APIs on `/api` while serving rendered pages on other paths which are not managed by OpenAPI schema in a single application.
370+
371+
You can add some lines to selectively validate only paths under `/api` while bypassing others:
372+
373+
```diff
374+
env[OpenapiFirst::PATH] = request.path.to_s.sub(%r"^/api", "")
375+
376+
+ # Only validate paths under /api/
377+
+ if request.path.start_with?('/api/')
378+
super
379+
+ else
380+
+ @app.call(env)
381+
+ end
382+
end
383+
```
384+
385+
And the final code is:
386+
387+
```ruby
388+
class CustomOpenAPIValidation < OpenapiFirst::Middlewares::RequestValidation
389+
def call(env)
390+
request = Rack::Request.new(env)
391+
392+
# Strip the "/api" prefix for schema matching
393+
env[OpenapiFirst::PATH] = request.path.to_s.sub(%r"^/api", "")
394+
395+
# Only validate paths under /api/
396+
if request.path.start_with?('/api/')
397+
super
398+
else
399+
@app.call(env)
400+
end
401+
end
402+
end
403+
404+
use CustomOpenAPIValidation, 'openapi.yaml'
405+
use OpenapiFirst::Middlewares::ResponseValidation, 'openapi.yaml'
406+
```
407+
330408
## Development
331409

332410
Run `bin/setup` to install dependencies.

0 commit comments

Comments
 (0)