Filtering and Sorting
Complex queries with string patterns, numeric ranges, and logical operators
API Definition
config/apis/bold_falcon.rb
rb
# frozen_string_literal: true
Apiwork::API.define '/bold_falcon' do
key_format :camel
export :openapi
export :typescript
export :zod
resources :articles
endModels
app/models/bold_falcon/article.rb
rb
# frozen_string_literal: true
module BoldFalcon
class Article < ApplicationRecord
belongs_to :category, optional: true
enum :status, { draft: 0, archived: 1, published: 2 }
validates :title, presence: true
end
endDatabase Table
| Column | Type | Nullable | Default |
|---|---|---|---|
| id | string | ||
| body | text | ✓ | |
| category_id | string | ✓ | |
| created_at | datetime | ||
| published_on | date | ✓ | |
| rating | decimal | ✓ | |
| status | integer | 0 | |
| title | string | ||
| updated_at | datetime | ||
| view_count | integer | ✓ | 0 |
app/models/bold_falcon/category.rb
rb
# frozen_string_literal: true
module BoldFalcon
class Category < ApplicationRecord
has_many :articles, dependent: :nullify
validates :name, :slug, presence: true
end
endDatabase Table
| Column | Type | Nullable | Default |
|---|---|---|---|
| id | string | ||
| created_at | datetime | ||
| name | string | ||
| slug | string | ||
| updated_at | datetime |
Representations
app/representations/bold_falcon/article_representation.rb
rb
# frozen_string_literal: true
module BoldFalcon
class ArticleRepresentation < Apiwork::Representation::Base
attribute :id
attribute :title, filterable: true, writable: true
attribute :body, writable: true
attribute :status, filterable: true, sortable: true, writable: true
attribute :view_count, filterable: true, sortable: true
attribute :rating
attribute :published_on, filterable: true, sortable: true, writable: true
attribute :created_at, sortable: true
attribute :updated_at, sortable: true
belongs_to :category, filterable: true
end
endapp/representations/bold_falcon/category_representation.rb
rb
# frozen_string_literal: true
module BoldFalcon
class CategoryRepresentation < Apiwork::Representation::Base
attribute :id
attribute :name, filterable: true
attribute :slug
end
endContracts
app/contracts/bold_falcon/article_contract.rb
rb
# frozen_string_literal: true
module BoldFalcon
class ArticleContract < Apiwork::Contract::Base
representation ArticleRepresentation
end
endControllers
app/controllers/bold_falcon/articles_controller.rb
rb
# frozen_string_literal: true
module BoldFalcon
class ArticlesController < ApplicationController
before_action :set_article, only: %i[show update destroy]
def index
articles = Article.all
expose articles
end
def show
expose article
end
def create
article = Article.create(contract.body[:article])
expose article
end
def update
article.update(contract.body[:article])
expose article
end
def destroy
article.destroy
expose article
end
private
attr_reader :article
def set_article
@article = Article.find(params[:id])
end
end
endRequest Examples
Filter by status
Request
http
GET /bold_falcon/articles?filter[status][eq]=publishedResponse 200
json
{
"articles": [
{
"id": "980bb55a-45bc-531b-a571-31b7d4d0a0ce",
"title": "Published Article",
"body": null,
"status": "published",
"viewCount": 0,
"rating": null,
"publishedOn": null,
"createdAt": "2024-01-01T12:00:00.000Z",
"updatedAt": "2024-01-01T12:00:00.000Z"
}
],
"pagination": {
"items": 1,
"total": 1,
"current": 1,
"next": null,
"prev": null
}
}Filter by title pattern
Request
http
GET /bold_falcon/articles?filter[title][contains]=RailsResponse 200
json
{
"articles": [
{
"id": "980bb55a-45bc-531b-a571-31b7d4d0a0ce",
"title": "Getting Started with Rails",
"body": null,
"status": "published",
"viewCount": 0,
"rating": null,
"publishedOn": null,
"createdAt": "2024-01-01T12:00:00.000Z",
"updatedAt": "2024-01-01T12:00:00.000Z"
}
],
"pagination": {
"items": 1,
"total": 1,
"current": 1,
"next": null,
"prev": null
}
}Sort by date
Request
http
GET /bold_falcon/articles?sort[published_on]=descResponse 200
json
{
"articles": [
{
"id": "66187cb1-6c7d-57b9-95bb-6de6ad564dad",
"title": "New Article",
"body": null,
"status": "published",
"viewCount": 0,
"rating": null,
"publishedOn": "2024-06-01",
"createdAt": "2024-01-01T12:00:00.000Z",
"updatedAt": "2024-01-01T12:00:00.000Z"
},
{
"id": "980bb55a-45bc-531b-a571-31b7d4d0a0ce",
"title": "Old Article",
"body": null,
"status": "published",
"viewCount": 0,
"rating": null,
"publishedOn": "2024-01-01",
"createdAt": "2024-01-01T12:00:00.000Z",
"updatedAt": "2024-01-01T12:00:00.000Z"
}
],
"pagination": {
"items": 2,
"total": 1,
"current": 1,
"next": null,
"prev": null
}
}Multiple sort fields
Request
http
GET /bold_falcon/articles?sort[status]=asc&sort[published_on]=descResponse 200
json
{
"articles": [
{
"id": "e8c30b71-ec2b-5287-ba57-5143a67ded78",
"title": "Draft 2",
"body": null,
"status": "draft",
"viewCount": 0,
"rating": null,
"publishedOn": "2024-03-01",
"createdAt": "2024-01-01T12:00:00.000Z",
"updatedAt": "2024-01-01T12:00:00.000Z"
},
{
"id": "980bb55a-45bc-531b-a571-31b7d4d0a0ce",
"title": "Draft 1",
"body": null,
"status": "draft",
"viewCount": 0,
"rating": null,
"publishedOn": "2024-01-01",
"createdAt": "2024-01-01T12:00:00.000Z",
"updatedAt": "2024-01-01T12:00:00.000Z"
},
{
"id": "66187cb1-6c7d-57b9-95bb-6de6ad564dad",
"title": "Published 1",
"body": null,
"status": "published",
"viewCount": 0,
"rating": null,
"publishedOn": "2024-02-01",
"createdAt": "2024-01-01T12:00:00.000Z",
"updatedAt": "2024-01-01T12:00:00.000Z"
}
],
"pagination": {
"items": 3,
"total": 1,
"current": 1,
"next": null,
"prev": null
}
}Filter by date range
Request
http
GET /bold_falcon/articles?filter[published_on][gte]=2024-01-01&filter[published_on][lt]=2024-02-01Response 200
json
{
"articles": [
{
"id": "980bb55a-45bc-531b-a571-31b7d4d0a0ce",
"title": "January Article",
"body": null,
"status": "published",
"viewCount": 0,
"rating": null,
"publishedOn": "2024-01-15",
"createdAt": "2024-01-01T12:00:00.000Z",
"updatedAt": "2024-01-01T12:00:00.000Z"
}
],
"pagination": {
"items": 1,
"total": 1,
"current": 1,
"next": null,
"prev": null
}
}Filter by view count
Request
http
GET /bold_falcon/articles?filter[view_count][gt]=100Response 200
json
{
"articles": [
{
"id": "980bb55a-45bc-531b-a571-31b7d4d0a0ce",
"title": "Popular Article",
"body": null,
"status": "published",
"viewCount": 500,
"rating": null,
"publishedOn": null,
"createdAt": "2024-01-01T12:00:00.000Z",
"updatedAt": "2024-01-01T12:00:00.000Z"
}
],
"pagination": {
"items": 1,
"total": 1,
"current": 1,
"next": null,
"prev": null
}
}Combined filter and sort
Request
http
GET /bold_falcon/articles?filter[status][eq]=published&sort[view_count]=descResponse 200
json
{
"articles": [
{
"id": "980bb55a-45bc-531b-a571-31b7d4d0a0ce",
"title": "Popular Published",
"body": null,
"status": "published",
"viewCount": 1000,
"rating": null,
"publishedOn": null,
"createdAt": "2024-01-01T12:00:00.000Z",
"updatedAt": "2024-01-01T12:00:00.000Z"
},
{
"id": "e8c30b71-ec2b-5287-ba57-5143a67ded78",
"title": "Less Popular Published",
"body": null,
"status": "published",
"viewCount": 100,
"rating": null,
"publishedOn": null,
"createdAt": "2024-01-01T12:00:00.000Z",
"updatedAt": "2024-01-01T12:00:00.000Z"
}
],
"pagination": {
"items": 2,
"total": 1,
"current": 1,
"next": null,
"prev": null
}
}Filter by category
Request
http
GET /bold_falcon/articles?filter[category][name][eq]=TechnologyResponse 200
json
{
"articles": [
{
"id": "980bb55a-45bc-531b-a571-31b7d4d0a0ce",
"title": "Tech Article",
"body": null,
"status": "published",
"viewCount": 0,
"rating": null,
"publishedOn": null,
"createdAt": "2024-01-01T12:00:00.000Z",
"updatedAt": "2024-01-01T12:00:00.000Z"
}
],
"pagination": {
"items": 1,
"total": 1,
"current": 1,
"next": null,
"prev": null
}
}Generated Output
Introspection
json
{
"base_path": "/bold_falcon",
"enums": {
"article_status": {
"deprecated": false,
"description": null,
"example": null,
"values": [
"draft",
"archived",
"published"
]
},
"layer": {
"deprecated": false,
"description": null,
"example": null,
"values": [
"http",
"contract",
"domain"
]
},
"sort_direction": {
"deprecated": false,
"description": null,
"example": null,
"values": [
"asc",
"desc"
]
}
},
"error_codes": {
"unprocessable_entity": {
"description": "Unprocessable Entity",
"status": 422
}
},
"info": null,
"resources": {
"articles": {
"actions": {
"index": {
"deprecated": false,
"description": null,
"method": "get",
"operation_id": null,
"path": "/articles",
"raises": [],
"request": {
"body": {},
"query": {
"filter": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "union",
"discriminator": null,
"variants": [
{
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "reference",
"reference": "article_filter"
},
{
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "array",
"max": null,
"min": null,
"of": {
"default": null,
"deprecated": null,
"description": null,
"example": null,
"nullable": null,
"optional": null,
"type": "reference",
"reference": "article_filter"
},
"shape": {}
}
]
},
"include": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "reference",
"reference": "article_include"
},
"page": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "reference",
"reference": "article_page"
},
"sort": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "union",
"discriminator": null,
"variants": [
{
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "reference",
"reference": "article_sort"
},
{
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "array",
"max": null,
"min": null,
"of": {
"default": null,
"deprecated": null,
"description": null,
"example": null,
"nullable": null,
"optional": null,
"type": "reference",
"reference": "article_sort"
},
"shape": {}
}
]
}
}
},
"response": {
"body": {
"default": null,
"deprecated": null,
"description": null,
"example": null,
"nullable": null,
"optional": null,
"type": "union",
"discriminator": null,
"variants": [
{
"default": null,
"deprecated": null,
"description": null,
"example": null,
"nullable": null,
"optional": null,
"type": "reference",
"reference": "article_index_success_response_body"
},
{
"default": null,
"deprecated": null,
"description": null,
"example": null,
"nullable": null,
"optional": null,
"type": "reference",
"reference": "error_response_body"
}
]
},
"no_content": false
},
"summary": null,
"tags": []
},
"show": {
"deprecated": false,
"description": null,
"method": "get",
"operation_id": null,
"path": "/articles/:id",
"raises": [],
"request": {
"body": {},
"query": {
"include": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "reference",
"reference": "article_include"
}
}
},
"response": {
"body": {
"default": null,
"deprecated": null,
"description": null,
"example": null,
"nullable": null,
"optional": null,
"type": "union",
"discriminator": null,
"variants": [
{
"default": null,
"deprecated": null,
"description": null,
"example": null,
"nullable": null,
"optional": null,
"type": "reference",
"reference": "article_show_success_response_body"
},
{
"default": null,
"deprecated": null,
"description": null,
"example": null,
"nullable": null,
"optional": null,
"type": "reference",
"reference": "error_response_body"
}
]
},
"no_content": false
},
"summary": null,
"tags": []
},
"create": {
"deprecated": false,
"description": null,
"method": "post",
"operation_id": null,
"path": "/articles",
"raises": [
"unprocessable_entity"
],
"request": {
"body": {
"article": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "reference",
"reference": "article_create_payload"
}
},
"query": {
"include": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "reference",
"reference": "article_include"
}
}
},
"response": {
"body": {
"default": null,
"deprecated": null,
"description": null,
"example": null,
"nullable": null,
"optional": null,
"type": "union",
"discriminator": null,
"variants": [
{
"default": null,
"deprecated": null,
"description": null,
"example": null,
"nullable": null,
"optional": null,
"type": "reference",
"reference": "article_create_success_response_body"
},
{
"default": null,
"deprecated": null,
"description": null,
"example": null,
"nullable": null,
"optional": null,
"type": "reference",
"reference": "error_response_body"
}
]
},
"no_content": false
},
"summary": null,
"tags": []
},
"update": {
"deprecated": false,
"description": null,
"method": "patch",
"operation_id": null,
"path": "/articles/:id",
"raises": [
"unprocessable_entity"
],
"request": {
"body": {
"article": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "reference",
"reference": "article_update_payload"
}
},
"query": {
"include": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "reference",
"reference": "article_include"
}
}
},
"response": {
"body": {
"default": null,
"deprecated": null,
"description": null,
"example": null,
"nullable": null,
"optional": null,
"type": "union",
"discriminator": null,
"variants": [
{
"default": null,
"deprecated": null,
"description": null,
"example": null,
"nullable": null,
"optional": null,
"type": "reference",
"reference": "article_update_success_response_body"
},
{
"default": null,
"deprecated": null,
"description": null,
"example": null,
"nullable": null,
"optional": null,
"type": "reference",
"reference": "error_response_body"
}
]
},
"no_content": false
},
"summary": null,
"tags": []
},
"destroy": {
"deprecated": false,
"description": null,
"method": "delete",
"operation_id": null,
"path": "/articles/:id",
"raises": [],
"request": {
"body": {},
"query": {
"include": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "reference",
"reference": "article_include"
}
}
},
"response": {
"body": {
"default": null,
"deprecated": null,
"description": null,
"example": null,
"nullable": null,
"optional": null,
"type": null
},
"no_content": true
},
"summary": null,
"tags": []
}
},
"identifier": "articles",
"parent_identifiers": [],
"path": "articles",
"resources": {}
}
},
"types": {
"article": {
"deprecated": false,
"description": null,
"discriminator": null,
"example": null,
"extends": [],
"shape": {
"body": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": true,
"optional": false,
"type": "string",
"format": null,
"max": null,
"min": null
},
"category": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": true,
"optional": true,
"type": "reference",
"reference": "category"
},
"created_at": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "datetime"
},
"id": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "string",
"format": null,
"max": null,
"min": null
},
"published_on": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": true,
"optional": false,
"type": "date"
},
"rating": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": true,
"optional": false,
"type": "decimal",
"max": null,
"min": null
},
"status": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "string",
"enum": "article_status",
"format": null,
"max": null,
"min": null
},
"title": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "string",
"format": null,
"max": null,
"min": null
},
"updated_at": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "datetime"
},
"view_count": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": true,
"optional": false,
"type": "integer",
"format": null,
"max": null,
"min": null
}
},
"type": "object",
"variants": []
},
"article_create_payload": {
"deprecated": false,
"description": null,
"discriminator": null,
"example": null,
"extends": [],
"shape": {
"body": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": true,
"optional": true,
"type": "string",
"format": null,
"max": null,
"min": null
},
"published_on": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": true,
"optional": true,
"type": "date"
},
"status": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "string",
"enum": "article_status",
"format": null,
"max": null,
"min": null
},
"title": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "string",
"format": null,
"max": null,
"min": null
}
},
"type": "object",
"variants": []
},
"article_create_success_response_body": {
"deprecated": false,
"description": null,
"discriminator": null,
"example": null,
"extends": [],
"shape": {
"article": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "reference",
"reference": "article"
},
"meta": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "object",
"partial": false,
"shape": {}
}
},
"type": "object",
"variants": []
},
"article_filter": {
"deprecated": false,
"description": null,
"discriminator": null,
"example": null,
"extends": [],
"shape": {
"AND": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "array",
"max": null,
"min": null,
"of": {
"default": null,
"deprecated": null,
"description": null,
"example": null,
"nullable": null,
"optional": null,
"type": "reference",
"reference": "article_filter"
},
"shape": {}
},
"NOT": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "reference",
"reference": "article_filter"
},
"OR": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "array",
"max": null,
"min": null,
"of": {
"default": null,
"deprecated": null,
"description": null,
"example": null,
"nullable": null,
"optional": null,
"type": "reference",
"reference": "article_filter"
},
"shape": {}
},
"category": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "reference",
"reference": "category_filter"
},
"published_on": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "union",
"discriminator": null,
"variants": [
{
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "date"
},
{
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "reference",
"reference": "nullable_date_filter"
}
]
},
"status": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "reference",
"reference": "article_status_filter"
},
"title": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "union",
"discriminator": null,
"variants": [
{
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "string",
"format": null,
"max": null,
"min": null
},
{
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "reference",
"reference": "string_filter"
}
]
},
"view_count": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "union",
"discriminator": null,
"variants": [
{
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "integer",
"format": null,
"max": null,
"min": null
},
{
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "reference",
"reference": "nullable_integer_filter"
}
]
}
},
"type": "object",
"variants": []
},
"article_include": {
"deprecated": false,
"description": null,
"discriminator": null,
"example": null,
"extends": [],
"shape": {
"category": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "boolean"
}
},
"type": "object",
"variants": []
},
"article_index_success_response_body": {
"deprecated": false,
"description": null,
"discriminator": null,
"example": null,
"extends": [],
"shape": {
"pagination": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "reference",
"reference": "offset_pagination"
},
"articles": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "array",
"max": null,
"min": null,
"of": {
"default": null,
"deprecated": null,
"description": null,
"example": null,
"nullable": null,
"optional": null,
"type": "reference",
"reference": "article"
},
"shape": {}
},
"meta": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "object",
"partial": false,
"shape": {}
}
},
"type": "object",
"variants": []
},
"article_page": {
"deprecated": false,
"description": null,
"discriminator": null,
"example": null,
"extends": [],
"shape": {
"number": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "integer",
"format": null,
"max": null,
"min": 1
},
"size": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "integer",
"format": null,
"max": 100,
"min": 1
}
},
"type": "object",
"variants": []
},
"article_show_success_response_body": {
"deprecated": false,
"description": null,
"discriminator": null,
"example": null,
"extends": [],
"shape": {
"article": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "reference",
"reference": "article"
},
"meta": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "object",
"partial": false,
"shape": {}
}
},
"type": "object",
"variants": []
},
"article_sort": {
"deprecated": false,
"description": null,
"discriminator": null,
"example": null,
"extends": [],
"shape": {
"created_at": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "reference",
"reference": "sort_direction"
},
"published_on": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "reference",
"reference": "sort_direction"
},
"status": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "reference",
"reference": "sort_direction"
},
"updated_at": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "reference",
"reference": "sort_direction"
},
"view_count": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "reference",
"reference": "sort_direction"
}
},
"type": "object",
"variants": []
},
"article_status_filter": {
"deprecated": false,
"description": null,
"discriminator": null,
"example": null,
"extends": [],
"shape": {},
"type": "union",
"variants": [
{
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "reference",
"reference": "article_status"
},
{
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "object",
"partial": true,
"shape": {
"eq": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "reference",
"reference": "article_status"
},
"in": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "array",
"max": null,
"min": null,
"of": {
"default": null,
"deprecated": null,
"description": null,
"example": null,
"nullable": null,
"optional": null,
"type": "reference",
"reference": "article_status"
},
"shape": {}
}
}
}
]
},
"article_update_payload": {
"deprecated": false,
"description": null,
"discriminator": null,
"example": null,
"extends": [],
"shape": {
"body": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": true,
"optional": true,
"type": "string",
"format": null,
"max": null,
"min": null
},
"published_on": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": true,
"optional": true,
"type": "date"
},
"status": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "string",
"enum": "article_status",
"format": null,
"max": null,
"min": null
},
"title": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "string",
"format": null,
"max": null,
"min": null
}
},
"type": "object",
"variants": []
},
"article_update_success_response_body": {
"deprecated": false,
"description": null,
"discriminator": null,
"example": null,
"extends": [],
"shape": {
"article": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "reference",
"reference": "article"
},
"meta": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "object",
"partial": false,
"shape": {}
}
},
"type": "object",
"variants": []
},
"category": {
"deprecated": false,
"description": null,
"discriminator": null,
"example": null,
"extends": [],
"shape": {
"id": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "string",
"format": null,
"max": null,
"min": null
},
"name": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "string",
"format": null,
"max": null,
"min": null
},
"slug": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "string",
"format": null,
"max": null,
"min": null
}
},
"type": "object",
"variants": []
},
"category_create_payload": {
"deprecated": false,
"description": null,
"discriminator": null,
"example": null,
"extends": [],
"shape": {},
"type": "object",
"variants": []
},
"category_filter": {
"deprecated": false,
"description": null,
"discriminator": null,
"example": null,
"extends": [],
"shape": {
"AND": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "array",
"max": null,
"min": null,
"of": {
"default": null,
"deprecated": null,
"description": null,
"example": null,
"nullable": null,
"optional": null,
"type": "reference",
"reference": "category_filter"
},
"shape": {}
},
"NOT": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "reference",
"reference": "category_filter"
},
"OR": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "array",
"max": null,
"min": null,
"of": {
"default": null,
"deprecated": null,
"description": null,
"example": null,
"nullable": null,
"optional": null,
"type": "reference",
"reference": "category_filter"
},
"shape": {}
},
"name": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "union",
"discriminator": null,
"variants": [
{
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "string",
"format": null,
"max": null,
"min": null
},
{
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "reference",
"reference": "string_filter"
}
]
}
},
"type": "object",
"variants": []
},
"category_update_payload": {
"deprecated": false,
"description": null,
"discriminator": null,
"example": null,
"extends": [],
"shape": {},
"type": "object",
"variants": []
},
"date_filter": {
"deprecated": false,
"description": null,
"discriminator": null,
"example": null,
"extends": [],
"shape": {
"between": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "reference",
"reference": "date_filter_between"
},
"eq": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "date"
},
"gt": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "date"
},
"gte": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "date"
},
"in": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "array",
"max": null,
"min": null,
"of": {
"default": null,
"deprecated": null,
"description": null,
"example": null,
"nullable": null,
"optional": null,
"type": "date"
},
"shape": {}
},
"lt": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "date"
},
"lte": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "date"
}
},
"type": "object",
"variants": []
},
"date_filter_between": {
"deprecated": false,
"description": null,
"discriminator": null,
"example": null,
"extends": [],
"shape": {
"from": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "date"
},
"to": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "date"
}
},
"type": "object",
"variants": []
},
"error": {
"deprecated": false,
"description": null,
"discriminator": null,
"example": null,
"extends": [],
"shape": {
"issues": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "array",
"max": null,
"min": null,
"of": {
"default": null,
"deprecated": null,
"description": null,
"example": null,
"nullable": null,
"optional": null,
"type": "reference",
"reference": "issue"
},
"shape": {}
},
"layer": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "reference",
"reference": "layer"
}
},
"type": "object",
"variants": []
},
"error_response_body": {
"deprecated": false,
"description": null,
"discriminator": null,
"example": null,
"extends": [
"error"
],
"shape": {},
"type": "object",
"variants": []
},
"integer_filter": {
"deprecated": false,
"description": null,
"discriminator": null,
"example": null,
"extends": [],
"shape": {
"between": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "reference",
"reference": "integer_filter_between"
},
"eq": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "integer",
"format": null,
"max": null,
"min": null
},
"gt": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "integer",
"format": null,
"max": null,
"min": null
},
"gte": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "integer",
"format": null,
"max": null,
"min": null
},
"in": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "array",
"max": null,
"min": null,
"of": {
"default": null,
"deprecated": null,
"description": null,
"example": null,
"nullable": null,
"optional": null,
"type": "integer",
"format": null,
"max": null,
"min": null
},
"shape": {}
},
"lt": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "integer",
"format": null,
"max": null,
"min": null
},
"lte": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "integer",
"format": null,
"max": null,
"min": null
}
},
"type": "object",
"variants": []
},
"integer_filter_between": {
"deprecated": false,
"description": null,
"discriminator": null,
"example": null,
"extends": [],
"shape": {
"from": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "integer",
"format": null,
"max": null,
"min": null
},
"to": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "integer",
"format": null,
"max": null,
"min": null
}
},
"type": "object",
"variants": []
},
"issue": {
"deprecated": false,
"description": null,
"discriminator": null,
"example": null,
"extends": [],
"shape": {
"code": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "string",
"format": null,
"max": null,
"min": null
},
"detail": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "string",
"format": null,
"max": null,
"min": null
},
"meta": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "object",
"partial": false,
"shape": {}
},
"path": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "array",
"max": null,
"min": null,
"of": {
"default": null,
"deprecated": null,
"description": null,
"example": null,
"nullable": null,
"optional": null,
"type": "string",
"format": null,
"max": null,
"min": null
},
"shape": {}
},
"pointer": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "string",
"format": null,
"max": null,
"min": null
}
},
"type": "object",
"variants": []
},
"nullable_date_filter": {
"deprecated": false,
"description": null,
"discriminator": null,
"example": null,
"extends": [],
"shape": {
"between": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "reference",
"reference": "date_filter_between"
},
"eq": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "date"
},
"gt": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "date"
},
"gte": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "date"
},
"in": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "array",
"max": null,
"min": null,
"of": {
"default": null,
"deprecated": null,
"description": null,
"example": null,
"nullable": null,
"optional": null,
"type": "date"
},
"shape": {}
},
"lt": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "date"
},
"lte": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "date"
},
"null": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "boolean"
}
},
"type": "object",
"variants": []
},
"nullable_integer_filter": {
"deprecated": false,
"description": null,
"discriminator": null,
"example": null,
"extends": [],
"shape": {
"between": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "reference",
"reference": "integer_filter_between"
},
"eq": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "integer",
"format": null,
"max": null,
"min": null
},
"gt": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "integer",
"format": null,
"max": null,
"min": null
},
"gte": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "integer",
"format": null,
"max": null,
"min": null
},
"in": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "array",
"max": null,
"min": null,
"of": {
"default": null,
"deprecated": null,
"description": null,
"example": null,
"nullable": null,
"optional": null,
"type": "integer",
"format": null,
"max": null,
"min": null
},
"shape": {}
},
"lt": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "integer",
"format": null,
"max": null,
"min": null
},
"lte": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "integer",
"format": null,
"max": null,
"min": null
},
"null": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "boolean"
}
},
"type": "object",
"variants": []
},
"offset_pagination": {
"deprecated": false,
"description": null,
"discriminator": null,
"example": null,
"extends": [],
"shape": {
"current": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "integer",
"format": null,
"max": null,
"min": null
},
"items": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "integer",
"format": null,
"max": null,
"min": null
},
"next": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": true,
"optional": true,
"type": "integer",
"format": null,
"max": null,
"min": null
},
"prev": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": true,
"optional": true,
"type": "integer",
"format": null,
"max": null,
"min": null
},
"total": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "integer",
"format": null,
"max": null,
"min": null
}
},
"type": "object",
"variants": []
},
"string_filter": {
"deprecated": false,
"description": null,
"discriminator": null,
"example": null,
"extends": [],
"shape": {
"contains": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "string",
"format": null,
"max": null,
"min": null
},
"ends_with": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "string",
"format": null,
"max": null,
"min": null
},
"eq": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "string",
"format": null,
"max": null,
"min": null
},
"in": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "array",
"max": null,
"min": null,
"of": {
"default": null,
"deprecated": null,
"description": null,
"example": null,
"nullable": null,
"optional": null,
"type": "string",
"format": null,
"max": null,
"min": null
},
"shape": {}
},
"starts_with": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "string",
"format": null,
"max": null,
"min": null
}
},
"type": "object",
"variants": []
}
}
}TypeScript
ts
export interface Article {
body: null | string;
category?: Category | null;
createdAt: string;
id: string;
publishedOn: null | string;
rating: null | number;
status: ArticleStatus;
title: string;
updatedAt: string;
viewCount: null | number;
}
export interface ArticleCreatePayload {
body?: null | string;
publishedOn?: null | string;
status?: ArticleStatus;
title: string;
}
export interface ArticleCreateSuccessResponseBody {
article: Article;
meta?: Record<string, unknown>;
}
export interface ArticleFilter {
AND?: ArticleFilter[];
NOT?: ArticleFilter;
OR?: ArticleFilter[];
category?: CategoryFilter;
publishedOn?: NullableDateFilter | string;
status?: ArticleStatusFilter;
title?: StringFilter | string;
viewCount?: NullableIntegerFilter | number;
}
export interface ArticleInclude {
category?: boolean;
}
export interface ArticleIndexSuccessResponseBody {
articles: Article[];
meta?: Record<string, unknown>;
pagination: OffsetPagination;
}
export interface ArticlePage {
number?: number;
size?: number;
}
export interface ArticleShowSuccessResponseBody {
article: Article;
meta?: Record<string, unknown>;
}
export interface ArticleSort {
createdAt?: SortDirection;
publishedOn?: SortDirection;
status?: SortDirection;
updatedAt?: SortDirection;
viewCount?: SortDirection;
}
export type ArticleStatus = 'archived' | 'draft' | 'published';
export type ArticleStatusFilter = ArticleStatus | { eq?: ArticleStatus; in?: ArticleStatus[] };
export interface ArticleUpdatePayload {
body?: null | string;
publishedOn?: null | string;
status?: ArticleStatus;
title?: string;
}
export interface ArticleUpdateSuccessResponseBody {
article: Article;
meta?: Record<string, unknown>;
}
export interface ArticlesCreateRequest {
query: ArticlesCreateRequestQuery;
body: ArticlesCreateRequestBody;
}
export interface ArticlesCreateRequestBody {
article: ArticleCreatePayload;
}
export interface ArticlesCreateRequestQuery {
include?: ArticleInclude;
}
export interface ArticlesCreateResponse {
body: ArticlesCreateResponseBody;
}
export type ArticlesCreateResponseBody = ArticleCreateSuccessResponseBody | ErrorResponseBody;
export interface ArticlesDestroyRequest {
query: ArticlesDestroyRequestQuery;
}
export interface ArticlesDestroyRequestQuery {
include?: ArticleInclude;
}
export type ArticlesDestroyResponse = never;
export interface ArticlesIndexRequest {
query: ArticlesIndexRequestQuery;
}
export interface ArticlesIndexRequestQuery {
filter?: ArticleFilter | ArticleFilter[];
include?: ArticleInclude;
page?: ArticlePage;
sort?: ArticleSort | ArticleSort[];
}
export interface ArticlesIndexResponse {
body: ArticlesIndexResponseBody;
}
export type ArticlesIndexResponseBody = ArticleIndexSuccessResponseBody | ErrorResponseBody;
export interface ArticlesShowRequest {
query: ArticlesShowRequestQuery;
}
export interface ArticlesShowRequestQuery {
include?: ArticleInclude;
}
export interface ArticlesShowResponse {
body: ArticlesShowResponseBody;
}
export type ArticlesShowResponseBody = ArticleShowSuccessResponseBody | ErrorResponseBody;
export interface ArticlesUpdateRequest {
query: ArticlesUpdateRequestQuery;
body: ArticlesUpdateRequestBody;
}
export interface ArticlesUpdateRequestBody {
article: ArticleUpdatePayload;
}
export interface ArticlesUpdateRequestQuery {
include?: ArticleInclude;
}
export interface ArticlesUpdateResponse {
body: ArticlesUpdateResponseBody;
}
export type ArticlesUpdateResponseBody = ArticleUpdateSuccessResponseBody | ErrorResponseBody;
export interface Category {
id: string;
name: string;
slug: string;
}
export interface CategoryFilter {
AND?: CategoryFilter[];
NOT?: CategoryFilter;
OR?: CategoryFilter[];
name?: StringFilter | string;
}
export interface DateFilterBetween {
from?: string;
to?: string;
}
export interface Error {
issues: Issue[];
layer: Layer;
}
export type ErrorResponseBody = Error;
export interface IntegerFilterBetween {
from?: number;
to?: number;
}
export interface Issue {
code: string;
detail: string;
meta: Record<string, unknown>;
path: string[];
pointer: string;
}
export type Layer = 'contract' | 'domain' | 'http';
export interface NullableDateFilter {
between?: DateFilterBetween;
eq?: string;
gt?: string;
gte?: string;
in?: string[];
lt?: string;
lte?: string;
null?: boolean;
}
export interface NullableIntegerFilter {
between?: IntegerFilterBetween;
eq?: number;
gt?: number;
gte?: number;
in?: number[];
lt?: number;
lte?: number;
null?: boolean;
}
export interface OffsetPagination {
current: number;
items: number;
next?: null | number;
prev?: null | number;
total: number;
}
export type SortDirection = 'asc' | 'desc';
export interface StringFilter {
contains?: string;
endsWith?: string;
eq?: string;
in?: string[];
startsWith?: string;
}Zod
ts
import { z } from 'zod';
export const ArticleStatusSchema = z.enum(['archived', 'draft', 'published']);
export const LayerSchema = z.enum(['contract', 'domain', 'http']);
export const SortDirectionSchema = z.enum(['asc', 'desc']);
export const ArticleFilterSchema: z.ZodType<ArticleFilter> = z.lazy(() => z.object({
AND: z.array(ArticleFilterSchema).optional(),
NOT: ArticleFilterSchema.optional(),
OR: z.array(ArticleFilterSchema).optional(),
category: CategoryFilterSchema.optional(),
publishedOn: z.union([z.iso.date(), NullableDateFilterSchema]).optional(),
status: ArticleStatusFilterSchema.optional(),
title: z.union([z.string(), StringFilterSchema]).optional(),
viewCount: z.union([z.number().int(), NullableIntegerFilterSchema]).optional()
}));
export const CategoryFilterSchema: z.ZodType<CategoryFilter> = z.lazy(() => z.object({
AND: z.array(CategoryFilterSchema).optional(),
NOT: CategoryFilterSchema.optional(),
OR: z.array(CategoryFilterSchema).optional(),
name: z.union([z.string(), StringFilterSchema]).optional()
}));
export const ArticleCreatePayloadSchema = z.object({
body: z.string().nullable().optional(),
publishedOn: z.iso.date().nullable().optional(),
status: ArticleStatusSchema.optional(),
title: z.string()
});
export const ArticleIncludeSchema = z.object({
category: z.boolean().optional()
});
export const ArticlePageSchema = z.object({
number: z.number().int().min(1).optional(),
size: z.number().int().min(1).max(100).optional()
});
export const ArticleSortSchema = z.object({
createdAt: SortDirectionSchema.optional(),
publishedOn: SortDirectionSchema.optional(),
status: SortDirectionSchema.optional(),
updatedAt: SortDirectionSchema.optional(),
viewCount: SortDirectionSchema.optional()
});
export const ArticleStatusFilterSchema = z.union([
ArticleStatusSchema,
z.object({ eq: ArticleStatusSchema, in: z.array(ArticleStatusSchema) }).partial()
]);
export const ArticleUpdatePayloadSchema = z.object({
body: z.string().nullable().optional(),
publishedOn: z.iso.date().nullable().optional(),
status: ArticleStatusSchema.optional(),
title: z.string().optional()
});
export const CategorySchema = z.object({
id: z.string(),
name: z.string(),
slug: z.string()
});
export const DateFilterBetweenSchema = z.object({
from: z.iso.date().optional(),
to: z.iso.date().optional()
});
export const IntegerFilterBetweenSchema = z.object({
from: z.number().int().optional(),
to: z.number().int().optional()
});
export const IssueSchema = z.object({
code: z.string(),
detail: z.string(),
meta: z.record(z.string(), z.unknown()),
path: z.array(z.string()),
pointer: z.string()
});
export const OffsetPaginationSchema = z.object({
current: z.number().int(),
items: z.number().int(),
next: z.number().int().nullable().optional(),
prev: z.number().int().nullable().optional(),
total: z.number().int()
});
export const StringFilterSchema = z.object({
contains: z.string().optional(),
endsWith: z.string().optional(),
eq: z.string().optional(),
in: z.array(z.string()).optional(),
startsWith: z.string().optional()
});
export const ArticleSchema = z.object({
body: z.string().nullable(),
category: CategorySchema.nullable().optional(),
createdAt: z.iso.datetime(),
id: z.string(),
publishedOn: z.iso.date().nullable(),
rating: z.number().nullable(),
status: ArticleStatusSchema,
title: z.string(),
updatedAt: z.iso.datetime(),
viewCount: z.number().int().nullable()
});
export const ErrorSchema = z.object({
issues: z.array(IssueSchema),
layer: LayerSchema
});
export const NullableDateFilterSchema = z.object({
between: DateFilterBetweenSchema.optional(),
eq: z.iso.date().optional(),
gt: z.iso.date().optional(),
gte: z.iso.date().optional(),
in: z.array(z.iso.date()).optional(),
lt: z.iso.date().optional(),
lte: z.iso.date().optional(),
null: z.boolean().optional()
});
export const NullableIntegerFilterSchema = z.object({
between: IntegerFilterBetweenSchema.optional(),
eq: z.number().int().optional(),
gt: z.number().int().optional(),
gte: z.number().int().optional(),
in: z.array(z.number().int()).optional(),
lt: z.number().int().optional(),
lte: z.number().int().optional(),
null: z.boolean().optional()
});
export const ArticleCreateSuccessResponseBodySchema = z.object({
article: ArticleSchema,
meta: z.record(z.string(), z.unknown()).optional()
});
export const ArticleIndexSuccessResponseBodySchema = z.object({
articles: z.array(ArticleSchema),
meta: z.record(z.string(), z.unknown()).optional(),
pagination: OffsetPaginationSchema
});
export const ArticleShowSuccessResponseBodySchema = z.object({
article: ArticleSchema,
meta: z.record(z.string(), z.unknown()).optional()
});
export const ArticleUpdateSuccessResponseBodySchema = z.object({
article: ArticleSchema,
meta: z.record(z.string(), z.unknown()).optional()
});
export const ErrorResponseBodySchema = ErrorSchema;
export const ArticlesIndexRequestQuerySchema = z.object({
filter: z.union([ArticleFilterSchema, z.array(ArticleFilterSchema)]).optional(),
include: ArticleIncludeSchema.optional(),
page: ArticlePageSchema.optional(),
sort: z.union([ArticleSortSchema, z.array(ArticleSortSchema)]).optional()
});
export const ArticlesIndexRequestSchema = z.object({
query: ArticlesIndexRequestQuerySchema
});
export const ArticlesIndexResponseBodySchema = z.union([ArticleIndexSuccessResponseBodySchema, ErrorResponseBodySchema]);
export const ArticlesIndexResponseSchema = z.object({
body: ArticlesIndexResponseBodySchema
});
export const ArticlesShowRequestQuerySchema = z.object({
include: ArticleIncludeSchema.optional()
});
export const ArticlesShowRequestSchema = z.object({
query: ArticlesShowRequestQuerySchema
});
export const ArticlesShowResponseBodySchema = z.union([ArticleShowSuccessResponseBodySchema, ErrorResponseBodySchema]);
export const ArticlesShowResponseSchema = z.object({
body: ArticlesShowResponseBodySchema
});
export const ArticlesCreateRequestQuerySchema = z.object({
include: ArticleIncludeSchema.optional()
});
export const ArticlesCreateRequestBodySchema = z.object({
article: ArticleCreatePayloadSchema
});
export const ArticlesCreateRequestSchema = z.object({
query: ArticlesCreateRequestQuerySchema,
body: ArticlesCreateRequestBodySchema
});
export const ArticlesCreateResponseBodySchema = z.union([ArticleCreateSuccessResponseBodySchema, ErrorResponseBodySchema]);
export const ArticlesCreateResponseSchema = z.object({
body: ArticlesCreateResponseBodySchema
});
export const ArticlesUpdateRequestQuerySchema = z.object({
include: ArticleIncludeSchema.optional()
});
export const ArticlesUpdateRequestBodySchema = z.object({
article: ArticleUpdatePayloadSchema
});
export const ArticlesUpdateRequestSchema = z.object({
query: ArticlesUpdateRequestQuerySchema,
body: ArticlesUpdateRequestBodySchema
});
export const ArticlesUpdateResponseBodySchema = z.union([ArticleUpdateSuccessResponseBodySchema, ErrorResponseBodySchema]);
export const ArticlesUpdateResponseSchema = z.object({
body: ArticlesUpdateResponseBodySchema
});
export const ArticlesDestroyRequestQuerySchema = z.object({
include: ArticleIncludeSchema.optional()
});
export const ArticlesDestroyRequestSchema = z.object({
query: ArticlesDestroyRequestQuerySchema
});
export const ArticlesDestroyResponseSchema = z.never();
export interface Article {
body: null | string;
category?: Category | null;
createdAt: string;
id: string;
publishedOn: null | string;
rating: null | number;
status: ArticleStatus;
title: string;
updatedAt: string;
viewCount: null | number;
}
export interface ArticleCreatePayload {
body?: null | string;
publishedOn?: null | string;
status?: ArticleStatus;
title: string;
}
export interface ArticleCreateSuccessResponseBody {
article: Article;
meta?: Record<string, unknown>;
}
export interface ArticleFilter {
AND?: ArticleFilter[];
NOT?: ArticleFilter;
OR?: ArticleFilter[];
category?: CategoryFilter;
publishedOn?: NullableDateFilter | string;
status?: ArticleStatusFilter;
title?: StringFilter | string;
viewCount?: NullableIntegerFilter | number;
}
export interface ArticleInclude {
category?: boolean;
}
export interface ArticleIndexSuccessResponseBody {
articles: Article[];
meta?: Record<string, unknown>;
pagination: OffsetPagination;
}
export interface ArticlePage {
number?: number;
size?: number;
}
export interface ArticleShowSuccessResponseBody {
article: Article;
meta?: Record<string, unknown>;
}
export interface ArticleSort {
createdAt?: SortDirection;
publishedOn?: SortDirection;
status?: SortDirection;
updatedAt?: SortDirection;
viewCount?: SortDirection;
}
export type ArticleStatus = 'archived' | 'draft' | 'published';
export type ArticleStatusFilter = ArticleStatus | { eq?: ArticleStatus; in?: ArticleStatus[] };
export interface ArticleUpdatePayload {
body?: null | string;
publishedOn?: null | string;
status?: ArticleStatus;
title?: string;
}
export interface ArticleUpdateSuccessResponseBody {
article: Article;
meta?: Record<string, unknown>;
}
export interface ArticlesCreateRequest {
query: ArticlesCreateRequestQuery;
body: ArticlesCreateRequestBody;
}
export interface ArticlesCreateRequestBody {
article: ArticleCreatePayload;
}
export interface ArticlesCreateRequestQuery {
include?: ArticleInclude;
}
export interface ArticlesCreateResponse {
body: ArticlesCreateResponseBody;
}
export type ArticlesCreateResponseBody = ArticleCreateSuccessResponseBody | ErrorResponseBody;
export interface ArticlesDestroyRequest {
query: ArticlesDestroyRequestQuery;
}
export interface ArticlesDestroyRequestQuery {
include?: ArticleInclude;
}
export type ArticlesDestroyResponse = never;
export interface ArticlesIndexRequest {
query: ArticlesIndexRequestQuery;
}
export interface ArticlesIndexRequestQuery {
filter?: ArticleFilter | ArticleFilter[];
include?: ArticleInclude;
page?: ArticlePage;
sort?: ArticleSort | ArticleSort[];
}
export interface ArticlesIndexResponse {
body: ArticlesIndexResponseBody;
}
export type ArticlesIndexResponseBody = ArticleIndexSuccessResponseBody | ErrorResponseBody;
export interface ArticlesShowRequest {
query: ArticlesShowRequestQuery;
}
export interface ArticlesShowRequestQuery {
include?: ArticleInclude;
}
export interface ArticlesShowResponse {
body: ArticlesShowResponseBody;
}
export type ArticlesShowResponseBody = ArticleShowSuccessResponseBody | ErrorResponseBody;
export interface ArticlesUpdateRequest {
query: ArticlesUpdateRequestQuery;
body: ArticlesUpdateRequestBody;
}
export interface ArticlesUpdateRequestBody {
article: ArticleUpdatePayload;
}
export interface ArticlesUpdateRequestQuery {
include?: ArticleInclude;
}
export interface ArticlesUpdateResponse {
body: ArticlesUpdateResponseBody;
}
export type ArticlesUpdateResponseBody = ArticleUpdateSuccessResponseBody | ErrorResponseBody;
export interface Category {
id: string;
name: string;
slug: string;
}
export interface CategoryFilter {
AND?: CategoryFilter[];
NOT?: CategoryFilter;
OR?: CategoryFilter[];
name?: StringFilter | string;
}
export interface DateFilterBetween {
from?: string;
to?: string;
}
export interface Error {
issues: Issue[];
layer: Layer;
}
export type ErrorResponseBody = Error;
export interface IntegerFilterBetween {
from?: number;
to?: number;
}
export interface Issue {
code: string;
detail: string;
meta: Record<string, unknown>;
path: string[];
pointer: string;
}
export type Layer = 'contract' | 'domain' | 'http';
export interface NullableDateFilter {
between?: DateFilterBetween;
eq?: string;
gt?: string;
gte?: string;
in?: string[];
lt?: string;
lte?: string;
null?: boolean;
}
export interface NullableIntegerFilter {
between?: IntegerFilterBetween;
eq?: number;
gt?: number;
gte?: number;
in?: number[];
lt?: number;
lte?: number;
null?: boolean;
}
export interface OffsetPagination {
current: number;
items: number;
next?: null | number;
prev?: null | number;
total: number;
}
export type SortDirection = 'asc' | 'desc';
export interface StringFilter {
contains?: string;
endsWith?: string;
eq?: string;
in?: string[];
startsWith?: string;
}OpenAPI
yml
---
openapi: 3.1.0
info:
title: "/bold_falcon"
version: 1.0.0
paths:
"/articles":
get:
operationId: articlesIndex
parameters:
- in: query
name: filter
required: false
schema:
oneOf:
- "$ref": "#/components/schemas/articleFilter"
- items:
"$ref": "#/components/schemas/articleFilter"
type: array
- in: query
name: include
required: false
schema:
"$ref": "#/components/schemas/articleInclude"
- in: query
name: page
required: false
schema:
"$ref": "#/components/schemas/articlePage"
- in: query
name: sort
required: false
schema:
oneOf:
- "$ref": "#/components/schemas/articleSort"
- items:
"$ref": "#/components/schemas/articleSort"
type: array
responses:
'200':
content:
application/json:
schema:
"$ref": "#/components/schemas/articleIndexSuccessResponseBody"
description: Successful response
post:
operationId: articlesCreate
parameters:
- in: query
name: include
required: false
schema:
"$ref": "#/components/schemas/articleInclude"
requestBody:
content:
application/json:
schema:
properties:
article:
"$ref": "#/components/schemas/articleCreatePayload"
type: object
required:
- article
required: true
responses:
'200':
content:
application/json:
schema:
"$ref": "#/components/schemas/articleCreateSuccessResponseBody"
description: Successful response
'422':
description: Unprocessable Entity
content:
application/json:
schema:
"$ref": "#/components/schemas/errorResponseBody"
"/articles/{id}":
get:
operationId: articlesShow
parameters:
- in: path
name: id
required: true
schema:
type: string
- in: query
name: include
required: false
schema:
"$ref": "#/components/schemas/articleInclude"
responses:
'200':
content:
application/json:
schema:
"$ref": "#/components/schemas/articleShowSuccessResponseBody"
description: Successful response
patch:
operationId: articlesUpdate
parameters:
- in: path
name: id
required: true
schema:
type: string
- in: query
name: include
required: false
schema:
"$ref": "#/components/schemas/articleInclude"
requestBody:
content:
application/json:
schema:
properties:
article:
"$ref": "#/components/schemas/articleUpdatePayload"
type: object
required:
- article
required: true
responses:
'200':
content:
application/json:
schema:
"$ref": "#/components/schemas/articleUpdateSuccessResponseBody"
description: Successful response
'422':
description: Unprocessable Entity
content:
application/json:
schema:
"$ref": "#/components/schemas/errorResponseBody"
delete:
operationId: articlesDestroy
parameters:
- in: path
name: id
required: true
schema:
type: string
- in: query
name: include
required: false
schema:
"$ref": "#/components/schemas/articleInclude"
responses:
'204':
description: No content
components:
schemas:
article:
properties:
body:
type:
- string
- 'null'
category:
oneOf:
- "$ref": "#/components/schemas/category"
- type: 'null'
createdAt:
type: string
format: date-time
id:
type: string
publishedOn:
type:
- string
- 'null'
format: date
rating:
type:
- number
- 'null'
status:
enum:
- draft
- archived
- published
type: string
title:
type: string
updatedAt:
type: string
format: date-time
viewCount:
type:
- integer
- 'null'
type: object
required:
- body
- createdAt
- id
- publishedOn
- rating
- status
- title
- updatedAt
- viewCount
articleCreatePayload:
properties:
body:
type:
- string
- 'null'
publishedOn:
type:
- string
- 'null'
format: date
status:
enum:
- draft
- archived
- published
type: string
title:
type: string
type: object
required:
- title
articleCreateSuccessResponseBody:
properties:
article:
"$ref": "#/components/schemas/article"
meta:
properties: {}
type: object
type: object
required:
- article
articleFilter:
properties:
AND:
items:
"$ref": "#/components/schemas/articleFilter"
type: array
NOT:
"$ref": "#/components/schemas/articleFilter"
OR:
items:
"$ref": "#/components/schemas/articleFilter"
type: array
category:
"$ref": "#/components/schemas/categoryFilter"
publishedOn:
oneOf:
- type: string
format: date
- "$ref": "#/components/schemas/nullableDateFilter"
status:
"$ref": "#/components/schemas/articleStatusFilter"
title:
oneOf:
- type: string
- "$ref": "#/components/schemas/stringFilter"
viewCount:
oneOf:
- type: integer
- "$ref": "#/components/schemas/nullableIntegerFilter"
type: object
articleInclude:
properties:
category:
type: boolean
type: object
articleIndexSuccessResponseBody:
properties:
pagination:
"$ref": "#/components/schemas/offsetPagination"
articles:
items:
"$ref": "#/components/schemas/article"
type: array
meta:
properties: {}
type: object
type: object
required:
- pagination
- articles
articlePage:
properties:
number:
type: integer
minimum: 1
size:
type: integer
minimum: 1
maximum: 100
type: object
articleShowSuccessResponseBody:
properties:
article:
"$ref": "#/components/schemas/article"
meta:
properties: {}
type: object
type: object
required:
- article
articleSort:
properties:
createdAt:
enum:
- asc
- desc
type: string
publishedOn:
enum:
- asc
- desc
type: string
status:
enum:
- asc
- desc
type: string
updatedAt:
enum:
- asc
- desc
type: string
viewCount:
enum:
- asc
- desc
type: string
type: object
articleStatusFilter:
oneOf:
- enum:
- draft
- archived
- published
type: string
- properties:
eq:
enum:
- draft
- archived
- published
type: string
in:
items:
enum:
- draft
- archived
- published
type: string
type: array
type: object
required:
- eq
- in
articleUpdatePayload:
properties:
body:
type:
- string
- 'null'
publishedOn:
type:
- string
- 'null'
format: date
status:
enum:
- draft
- archived
- published
type: string
title:
type: string
type: object
articleUpdateSuccessResponseBody:
properties:
article:
"$ref": "#/components/schemas/article"
meta:
properties: {}
type: object
type: object
required:
- article
category:
properties:
id:
type: string
name:
type: string
slug:
type: string
type: object
required:
- id
- name
- slug
categoryFilter:
properties:
AND:
items:
"$ref": "#/components/schemas/categoryFilter"
type: array
NOT:
"$ref": "#/components/schemas/categoryFilter"
OR:
items:
"$ref": "#/components/schemas/categoryFilter"
type: array
name:
oneOf:
- type: string
- "$ref": "#/components/schemas/stringFilter"
type: object
dateFilterBetween:
properties:
from:
type: string
format: date
to:
type: string
format: date
type: object
error:
properties:
issues:
items:
"$ref": "#/components/schemas/issue"
type: array
layer:
enum:
- http
- contract
- domain
type: string
type: object
required:
- issues
- layer
errorResponseBody:
"$ref": "#/components/schemas/error"
integerFilterBetween:
properties:
from:
type: integer
to:
type: integer
type: object
issue:
properties:
code:
type: string
detail:
type: string
meta:
properties: {}
type: object
path:
items:
type: string
type: array
pointer:
type: string
type: object
required:
- code
- detail
- meta
- path
- pointer
nullableDateFilter:
properties:
between:
"$ref": "#/components/schemas/dateFilterBetween"
eq:
type: string
format: date
gt:
type: string
format: date
gte:
type: string
format: date
in:
items:
type: string
format: date
type: array
lt:
type: string
format: date
lte:
type: string
format: date
'null':
type: boolean
type: object
nullableIntegerFilter:
properties:
between:
"$ref": "#/components/schemas/integerFilterBetween"
eq:
type: integer
gt:
type: integer
gte:
type: integer
in:
items:
type: integer
type: array
lt:
type: integer
lte:
type: integer
'null':
type: boolean
type: object
offsetPagination:
properties:
current:
type: integer
items:
type: integer
next:
type:
- integer
- 'null'
prev:
type:
- integer
- 'null'
total:
type: integer
type: object
required:
- current
- items
- total
stringFilter:
properties:
contains:
type: string
endsWith:
type: string
eq:
type: string
in:
items:
type: string
type: array
startsWith:
type: string
type: object