counterfact does not support $ref with external yaml files
As the title says, counterfact does not seem to support referencing yaml files in the openapi specification. Example:
paths:
/metrics:
get:
operationId: getMetrics
tags:
- Default
responses:
'200':
description: Successful response
content:
application/json:
schema:
$ref: 'components/metrics.yaml#/components/schemas/MetricsResponse'
examples:
default:
$ref: 'components/examples.yaml#/examples/MetricsResponseExample'
'500':
description: Internal server error
content:
application/json:
schema:
$ref: 'components/errors.yaml#/components/schemas/ErrorResponse'
When opening the swagger docs, I see the following error:
Response schema
When using a single openapi spec file, it works as expected
Found a couple issues on json-schema-ref-parser that could be related
- https://github.com/APIDevTools/json-schema-ref-parser/issues/199
- https://github.com/APIDevTools/json-schema-ref-parser/issues/376
I did some digging and the bundled schema has some weird $ref values:
{
type: 'array',
items: {
'$ref': '#/paths/~1metrics/get/responses/200/content/application~1json/schema/allOf/0/properties/data/items'
}
}
For anyone having the same problem, my workaround was to bundle my openapi spec using redocly and use that file to serve counterfact. The downside is that the hot-reload will not work automatically.
package.json
{
"scripts": {
"openapi:bundle": "bunx redocly bundle api-spec/openapi.yaml -o api-spec/openapi.json",
"serve:mock": "bun run openapi:bundle && counterfact api-spec/openapi.json lib/server/mock"
}
}
Thanks! Is there a problem in Counterfact itself or just Swagger? I thought I'd worked around by merging external files at runtime but may have missed something.
It works if I use $.response[200].json() to return static data. Using $.response[200].random() returns a 500 status with the following error:
The Open API document does not specify a response for status code 200
These are the files it generates:
import type { items } from "../../../../../../../../~1metrics/get/responses/200/content/application~1json/schema/allOf/0/properties/data/items.js";
export type _0 = {
data: Array<items>;
meta?: { total?: number; next?: string; prev?: string };
};
Thanks, I'll have a look. If can you share the relevant sections from metrics.yaml and errors.yaml, that will help.
Sure!
openapi.yaml:
paths:
/metrics:
get:
operationId: getMetrics
responses:
'200':
description: Successful response
content:
application/json:
schema:
$ref: 'components/metrics.yaml#/components/schemas/MetricsResponse'
'500':
description: Internal server error
content:
application/json:
schema:
$ref: 'components/errors.yaml#/components/schemas/ErrorResponse'
metrics.yaml:
components:
schemas:
MetricAttributes:
type: object
required: [value]
properties:
value:
type: integer
example: 20
title:
type: string
description:
type: string
MetricResource:
allOf:
- type: object
properties:
type:
type: string
enum: [metric]
example: metric
attributes:
$ref: '#/components/schemas/MetricAttributes'
MetricsResponse:
allOf:
- type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/MetricResource'
errors.yaml
components:
schemas:
ErrorResponse:
type: object
required: [status, statusCode, message]
properties:
title:
type: string
code:
type: string
example: ERR_PERMISSION
message:
type: string
name:
type: string
example: BadRequestError