Inline Types
Define typed JSON columns with object shapes, arrays, and nested structures
API Definition
config/apis/curious_cat.rb
rb
# frozen_string_literal: true
Apiwork::API.define '/curious_cat' do
key_format :camel
export :openapi
export :typescript
export :zod
resources :profiles
endModels
app/models/curious_cat/profile.rb
rb
# frozen_string_literal: true
module CuriousCat
class Profile < ApplicationRecord
store :settings, accessors: [:theme, :notifications, :language]
serialize :tags, coder: JSON
store :metadata, coder: JSON
end
endDatabase Table
| Column | Type | Nullable | Default |
|---|---|---|---|
| id | string | ||
| addresses | json | ||
| created_at | datetime | ||
| string | |||
| metadata | text | ||
| name | string | ||
| preferences | json | ||
| settings | json | ||
| tags | text | ||
| updated_at | datetime |
Representations
app/representations/curious_cat/profile_representation.rb
rb
# frozen_string_literal: true
module CuriousCat
class ProfileRepresentation < Apiwork::Representation::Base
attribute :id
attribute :name, writable: true
attribute :email, format: :email, writable: true
attribute :settings, writable: true do
object do
string :theme
boolean :notifications
string :language
end
end
attribute :tags, writable: true do
array do
string
end
end
attribute :addresses, writable: true do
array do
object do
string :street
string :city
string :zip
boolean :primary
end
end
end
attribute :preferences, writable: true do
object do
object :ui do
string :theme
boolean :sidebar_collapsed
end
object :notifications do
boolean :email
boolean :push
end
end
end
attribute :metadata, type: :unknown, writable: true
attribute :created_at
attribute :updated_at
end
endContracts
app/contracts/curious_cat/profile_contract.rb
rb
# frozen_string_literal: true
module CuriousCat
class ProfileContract < Apiwork::Contract::Base
representation ProfileRepresentation
end
endControllers
app/controllers/curious_cat/profiles_controller.rb
rb
# frozen_string_literal: true
module CuriousCat
class ProfilesController < ApplicationController
before_action :set_profile, only: %i[show update destroy]
def index
profiles = Profile.all
expose profiles
end
def show
expose profile
end
def create
profile = Profile.create(contract.body[:profile])
expose profile
end
def update
profile.update(contract.body[:profile])
expose profile
end
def destroy
profile.destroy
expose profile
end
private
attr_reader :profile
def set_profile
@profile = Profile.find(params[:id])
end
end
endRequest Examples
Create a profile with all inline types
Request
http
POST /curious_cat/profiles
Content-Type: application/json
{
"profile": {
"name": "Alice",
"email": "alice@example.com",
"settings": {
"theme": "dark",
"notifications": true,
"language": "en"
},
"tags": [
"developer",
"typescript"
],
"addresses": [
{
"street": "123 Main St",
"city": "Stockholm",
"zip": "12345",
"primary": true
}
],
"preferences": {
"ui": {
"theme": "compact",
"sidebarCollapsed": false
},
"notifications": {
"email": true,
"push": false
}
},
"metadata": {
"source": "api",
"version": 2
}
}
}Response 201
json
{
"profile": {
"id": "696f7bb0-6a34-5c02-b53f-46e76dd02494",
"name": "Alice",
"email": "alice@example.com",
"settings": {
"theme": "dark",
"notifications": true,
"language": "en"
},
"tags": [
"developer",
"typescript"
],
"addresses": [
{
"street": "123 Main St",
"city": "Stockholm",
"zip": "12345",
"primary": true
}
],
"preferences": {
"ui": {
"theme": "compact",
"sidebarCollapsed": false
},
"notifications": {
"email": true,
"push": false
}
},
"metadata": {
"source": "api",
"version": 2
},
"createdAt": "2024-01-01T12:00:00.000Z",
"updatedAt": "2024-01-01T12:00:00.000Z"
}
}Update profile settings and tags
Request
http
PATCH /curious_cat/profiles/696f7bb0-6a34-5c02-b53f-46e76dd02494
Content-Type: application/json
{
"profile": {
"settings": {
"theme": "light",
"notifications": false,
"language": "sv"
},
"tags": [
"developer",
"ruby",
"rails"
],
"metadata": {
"source": "api",
"version": 3
}
}
}Response 200
json
{
"profile": {
"id": "696f7bb0-6a34-5c02-b53f-46e76dd02494",
"name": "Alice",
"email": "alice@example.com",
"settings": {
"theme": "light",
"notifications": false,
"language": "sv"
},
"tags": [
"developer",
"ruby",
"rails"
],
"addresses": [
{
"street": "123 Main St",
"city": "Stockholm",
"zip": "12345",
"primary": true
}
],
"preferences": {
"ui": {
"theme": "compact",
"sidebarCollapsed": false
},
"notifications": {
"email": true,
"push": false
}
},
"metadata": {
"source": "api",
"version": 3
},
"createdAt": "2024-01-01T12:00:00.000Z",
"updatedAt": "2024-01-01T12:00:00.000Z"
}
}Generated Output
Introspection
json
{
"base_path": "/curious_cat",
"enums": {
"layer": {
"deprecated": false,
"description": null,
"example": null,
"values": [
"http",
"contract",
"domain"
]
}
},
"error_codes": {
"unprocessable_entity": {
"description": "Unprocessable Entity",
"status": 422
}
},
"info": null,
"resources": {
"profiles": {
"actions": {
"index": {
"deprecated": false,
"description": null,
"method": "get",
"operation_id": null,
"path": "/profiles",
"raises": [],
"request": {
"body": {},
"query": {
"page": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "reference",
"reference": "profile_page"
}
}
},
"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": "profile_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": "/profiles/:id",
"raises": [],
"request": {
"body": {},
"query": {}
},
"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": "profile_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": "/profiles",
"raises": [
"unprocessable_entity"
],
"request": {
"body": {
"profile": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "reference",
"reference": "profile_create_payload"
}
},
"query": {}
},
"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": "profile_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": "/profiles/:id",
"raises": [
"unprocessable_entity"
],
"request": {
"body": {
"profile": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "reference",
"reference": "profile_update_payload"
}
},
"query": {}
},
"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": "profile_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": "/profiles/:id",
"raises": [],
"request": {
"body": {},
"query": {}
},
"response": {
"body": {
"default": null,
"deprecated": null,
"description": null,
"example": null,
"nullable": null,
"optional": null,
"type": null
},
"no_content": true
},
"summary": null,
"tags": []
}
},
"identifier": "profiles",
"parent_identifiers": [],
"path": "profiles",
"resources": {}
}
},
"types": {
"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": []
},
"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": []
},
"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": []
},
"profile": {
"deprecated": false,
"description": null,
"discriminator": null,
"example": null,
"extends": [],
"shape": {
"addresses": {
"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": "object",
"partial": null,
"shape": {
"city": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "string",
"format": null,
"max": null,
"min": null
},
"primary": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "boolean"
},
"street": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "string",
"format": null,
"max": null,
"min": null
},
"zip": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "string",
"format": null,
"max": null,
"min": null
}
}
},
"shape": {
"city": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "string",
"format": null,
"max": null,
"min": null
},
"primary": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "boolean"
},
"street": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "string",
"format": null,
"max": null,
"min": null
},
"zip": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "string",
"format": null,
"max": null,
"min": null
}
}
},
"created_at": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "datetime"
},
"email": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "string",
"format": "email",
"max": null,
"min": null
},
"id": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "string",
"format": null,
"max": null,
"min": null
},
"metadata": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "unknown"
},
"name": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "string",
"format": null,
"max": null,
"min": null
},
"preferences": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "object",
"partial": false,
"shape": {
"notifications": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "object",
"partial": false,
"shape": {
"email": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "boolean"
},
"push": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "boolean"
}
}
},
"ui": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "object",
"partial": false,
"shape": {
"sidebar_collapsed": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "boolean"
},
"theme": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "string",
"format": null,
"max": null,
"min": null
}
}
}
}
},
"settings": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "object",
"partial": false,
"shape": {
"language": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "string",
"format": null,
"max": null,
"min": null
},
"notifications": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "boolean"
},
"theme": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "string",
"format": null,
"max": null,
"min": null
}
}
},
"tags": {
"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": {}
},
"updated_at": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "datetime"
}
},
"type": "object",
"variants": []
},
"profile_create_payload": {
"deprecated": false,
"description": null,
"discriminator": null,
"example": null,
"extends": [],
"shape": {
"addresses": {
"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": "object",
"partial": null,
"shape": {
"city": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "string",
"format": null,
"max": null,
"min": null
},
"primary": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "boolean"
},
"street": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "string",
"format": null,
"max": null,
"min": null
},
"zip": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "string",
"format": null,
"max": null,
"min": null
}
}
},
"shape": {
"city": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "string",
"format": null,
"max": null,
"min": null
},
"primary": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "boolean"
},
"street": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "string",
"format": null,
"max": null,
"min": null
},
"zip": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "string",
"format": null,
"max": null,
"min": null
}
}
},
"email": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "string",
"format": "email",
"max": null,
"min": null
},
"metadata": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "unknown"
},
"name": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "string",
"format": null,
"max": null,
"min": null
},
"preferences": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "object",
"partial": false,
"shape": {
"notifications": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "object",
"partial": false,
"shape": {
"email": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "boolean"
},
"push": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "boolean"
}
}
},
"ui": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "object",
"partial": false,
"shape": {
"sidebar_collapsed": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "boolean"
},
"theme": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "string",
"format": null,
"max": null,
"min": null
}
}
}
}
},
"settings": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "object",
"partial": false,
"shape": {
"language": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "string",
"format": null,
"max": null,
"min": null
},
"notifications": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "boolean"
},
"theme": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "string",
"format": null,
"max": null,
"min": null
}
}
},
"tags": {
"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": {}
}
},
"type": "object",
"variants": []
},
"profile_create_success_response_body": {
"deprecated": false,
"description": null,
"discriminator": null,
"example": null,
"extends": [],
"shape": {
"meta": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "object",
"partial": false,
"shape": {}
},
"profile": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "reference",
"reference": "profile"
}
},
"type": "object",
"variants": []
},
"profile_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"
},
"meta": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "object",
"partial": false,
"shape": {}
},
"profiles": {
"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": "profile"
},
"shape": {}
}
},
"type": "object",
"variants": []
},
"profile_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": []
},
"profile_show_success_response_body": {
"deprecated": false,
"description": null,
"discriminator": null,
"example": null,
"extends": [],
"shape": {
"meta": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "object",
"partial": false,
"shape": {}
},
"profile": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "reference",
"reference": "profile"
}
},
"type": "object",
"variants": []
},
"profile_update_payload": {
"deprecated": false,
"description": null,
"discriminator": null,
"example": null,
"extends": [],
"shape": {
"addresses": {
"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": "object",
"partial": null,
"shape": {
"city": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "string",
"format": null,
"max": null,
"min": null
},
"primary": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "boolean"
},
"street": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "string",
"format": null,
"max": null,
"min": null
},
"zip": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "string",
"format": null,
"max": null,
"min": null
}
}
},
"shape": {
"city": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "string",
"format": null,
"max": null,
"min": null
},
"primary": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "boolean"
},
"street": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "string",
"format": null,
"max": null,
"min": null
},
"zip": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "string",
"format": null,
"max": null,
"min": null
}
}
},
"email": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "string",
"format": "email",
"max": null,
"min": null
},
"metadata": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "unknown"
},
"name": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "string",
"format": null,
"max": null,
"min": null
},
"preferences": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "object",
"partial": false,
"shape": {
"notifications": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "object",
"partial": false,
"shape": {
"email": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "boolean"
},
"push": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "boolean"
}
}
},
"ui": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "object",
"partial": false,
"shape": {
"sidebar_collapsed": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "boolean"
},
"theme": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "string",
"format": null,
"max": null,
"min": null
}
}
}
}
},
"settings": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "object",
"partial": false,
"shape": {
"language": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "string",
"format": null,
"max": null,
"min": null
},
"notifications": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "boolean"
},
"theme": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "string",
"format": null,
"max": null,
"min": null
}
}
},
"tags": {
"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": {}
}
},
"type": "object",
"variants": []
},
"profile_update_success_response_body": {
"deprecated": false,
"description": null,
"discriminator": null,
"example": null,
"extends": [],
"shape": {
"meta": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": true,
"type": "object",
"partial": false,
"shape": {}
},
"profile": {
"default": null,
"deprecated": false,
"description": null,
"example": null,
"nullable": false,
"optional": false,
"type": "reference",
"reference": "profile"
}
},
"type": "object",
"variants": []
}
}
}TypeScript
ts
export interface Error {
issues: Issue[];
layer: Layer;
}
export type ErrorResponseBody = Error;
export interface Issue {
code: string;
detail: string;
meta: Record<string, unknown>;
path: string[];
pointer: string;
}
export type Layer = 'contract' | 'domain' | 'http';
export interface OffsetPagination {
current: number;
items: number;
next?: null | number;
prev?: null | number;
total: number;
}
export interface Profile {
addresses: { city: string; primary: boolean; street: string; zip: string }[];
createdAt: string;
email: string;
id: string;
metadata: unknown;
name: string;
preferences: { notifications: { email: boolean; push: boolean }; ui: { sidebarCollapsed: boolean; theme: string } };
settings: { language: string; notifications: boolean; theme: string };
tags: string[];
updatedAt: string;
}
export interface ProfileCreatePayload {
addresses: { city: string; primary: boolean; street: string; zip: string }[];
email: string;
metadata: unknown;
name: string;
preferences: { notifications: { email: boolean; push: boolean }; ui: { sidebarCollapsed: boolean; theme: string } };
settings: { language: string; notifications: boolean; theme: string };
tags: string[];
}
export interface ProfileCreateSuccessResponseBody {
meta?: Record<string, unknown>;
profile: Profile;
}
export interface ProfileIndexSuccessResponseBody {
meta?: Record<string, unknown>;
pagination: OffsetPagination;
profiles: Profile[];
}
export interface ProfilePage {
number?: number;
size?: number;
}
export interface ProfileShowSuccessResponseBody {
meta?: Record<string, unknown>;
profile: Profile;
}
export interface ProfileUpdatePayload {
addresses?: { city: string; primary: boolean; street: string; zip: string }[];
email?: string;
metadata?: unknown;
name?: string;
preferences?: { notifications: { email: boolean; push: boolean }; ui: { sidebarCollapsed: boolean; theme: string } };
settings?: { language: string; notifications: boolean; theme: string };
tags?: string[];
}
export interface ProfileUpdateSuccessResponseBody {
meta?: Record<string, unknown>;
profile: Profile;
}
export interface ProfilesCreateRequest {
body: ProfilesCreateRequestBody;
}
export interface ProfilesCreateRequestBody {
profile: ProfileCreatePayload;
}
export interface ProfilesCreateResponse {
body: ProfilesCreateResponseBody;
}
export type ProfilesCreateResponseBody = ErrorResponseBody | ProfileCreateSuccessResponseBody;
export type ProfilesDestroyResponse = never;
export interface ProfilesIndexRequest {
query: ProfilesIndexRequestQuery;
}
export interface ProfilesIndexRequestQuery {
page?: ProfilePage;
}
export interface ProfilesIndexResponse {
body: ProfilesIndexResponseBody;
}
export type ProfilesIndexResponseBody = ErrorResponseBody | ProfileIndexSuccessResponseBody;
export interface ProfilesShowResponse {
body: ProfilesShowResponseBody;
}
export type ProfilesShowResponseBody = ErrorResponseBody | ProfileShowSuccessResponseBody;
export interface ProfilesUpdateRequest {
body: ProfilesUpdateRequestBody;
}
export interface ProfilesUpdateRequestBody {
profile: ProfileUpdatePayload;
}
export interface ProfilesUpdateResponse {
body: ProfilesUpdateResponseBody;
}
export type ProfilesUpdateResponseBody = ErrorResponseBody | ProfileUpdateSuccessResponseBody;Zod
ts
import { z } from 'zod';
export const LayerSchema = z.enum(['contract', 'domain', 'http']);
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 ProfileSchema = z.object({
addresses: z.array(z.object({ city: z.string(), primary: z.boolean(), street: z.string(), zip: z.string() })),
createdAt: z.iso.datetime(),
email: z.email(),
id: z.string(),
metadata: z.unknown(),
name: z.string(),
preferences: z.object({ notifications: z.object({ email: z.boolean(), push: z.boolean() }), ui: z.object({ sidebarCollapsed: z.boolean(), theme: z.string() }) }),
settings: z.object({ language: z.string(), notifications: z.boolean(), theme: z.string() }),
tags: z.array(z.string()),
updatedAt: z.iso.datetime()
});
export const ProfileCreatePayloadSchema = z.object({
addresses: z.array(z.object({ city: z.string(), primary: z.boolean(), street: z.string(), zip: z.string() })),
email: z.email(),
metadata: z.unknown(),
name: z.string(),
preferences: z.object({ notifications: z.object({ email: z.boolean(), push: z.boolean() }), ui: z.object({ sidebarCollapsed: z.boolean(), theme: z.string() }) }),
settings: z.object({ language: z.string(), notifications: z.boolean(), theme: z.string() }),
tags: z.array(z.string())
});
export const ProfilePageSchema = z.object({
number: z.number().int().min(1).optional(),
size: z.number().int().min(1).max(100).optional()
});
export const ProfileUpdatePayloadSchema = z.object({
addresses: z.array(z.object({ city: z.string(), primary: z.boolean(), street: z.string(), zip: z.string() })).optional(),
email: z.email().optional(),
metadata: z.unknown().optional(),
name: z.string().optional(),
preferences: z.object({ notifications: z.object({ email: z.boolean(), push: z.boolean() }), ui: z.object({ sidebarCollapsed: z.boolean(), theme: z.string() }) }).optional(),
settings: z.object({ language: z.string(), notifications: z.boolean(), theme: z.string() }).optional(),
tags: z.array(z.string()).optional()
});
export const ErrorSchema = z.object({
issues: z.array(IssueSchema),
layer: LayerSchema
});
export const ProfileCreateSuccessResponseBodySchema = z.object({
meta: z.record(z.string(), z.unknown()).optional(),
profile: ProfileSchema
});
export const ProfileIndexSuccessResponseBodySchema = z.object({
meta: z.record(z.string(), z.unknown()).optional(),
pagination: OffsetPaginationSchema,
profiles: z.array(ProfileSchema)
});
export const ProfileShowSuccessResponseBodySchema = z.object({
meta: z.record(z.string(), z.unknown()).optional(),
profile: ProfileSchema
});
export const ProfileUpdateSuccessResponseBodySchema = z.object({
meta: z.record(z.string(), z.unknown()).optional(),
profile: ProfileSchema
});
export const ErrorResponseBodySchema = ErrorSchema;
export const ProfilesIndexRequestQuerySchema = z.object({
page: ProfilePageSchema.optional()
});
export const ProfilesIndexRequestSchema = z.object({
query: ProfilesIndexRequestQuerySchema
});
export const ProfilesIndexResponseBodySchema = z.union([ProfileIndexSuccessResponseBodySchema, ErrorResponseBodySchema]);
export const ProfilesIndexResponseSchema = z.object({
body: ProfilesIndexResponseBodySchema
});
export const ProfilesShowResponseBodySchema = z.union([ProfileShowSuccessResponseBodySchema, ErrorResponseBodySchema]);
export const ProfilesShowResponseSchema = z.object({
body: ProfilesShowResponseBodySchema
});
export const ProfilesCreateRequestBodySchema = z.object({
profile: ProfileCreatePayloadSchema
});
export const ProfilesCreateRequestSchema = z.object({
body: ProfilesCreateRequestBodySchema
});
export const ProfilesCreateResponseBodySchema = z.union([ProfileCreateSuccessResponseBodySchema, ErrorResponseBodySchema]);
export const ProfilesCreateResponseSchema = z.object({
body: ProfilesCreateResponseBodySchema
});
export const ProfilesUpdateRequestBodySchema = z.object({
profile: ProfileUpdatePayloadSchema
});
export const ProfilesUpdateRequestSchema = z.object({
body: ProfilesUpdateRequestBodySchema
});
export const ProfilesUpdateResponseBodySchema = z.union([ProfileUpdateSuccessResponseBodySchema, ErrorResponseBodySchema]);
export const ProfilesUpdateResponseSchema = z.object({
body: ProfilesUpdateResponseBodySchema
});
export const ProfilesDestroyResponseSchema = z.never();
export interface Error {
issues: Issue[];
layer: Layer;
}
export type ErrorResponseBody = Error;
export interface Issue {
code: string;
detail: string;
meta: Record<string, unknown>;
path: string[];
pointer: string;
}
export type Layer = 'contract' | 'domain' | 'http';
export interface OffsetPagination {
current: number;
items: number;
next?: null | number;
prev?: null | number;
total: number;
}
export interface Profile {
addresses: { city: string; primary: boolean; street: string; zip: string }[];
createdAt: string;
email: string;
id: string;
metadata: unknown;
name: string;
preferences: { notifications: { email: boolean; push: boolean }; ui: { sidebarCollapsed: boolean; theme: string } };
settings: { language: string; notifications: boolean; theme: string };
tags: string[];
updatedAt: string;
}
export interface ProfileCreatePayload {
addresses: { city: string; primary: boolean; street: string; zip: string }[];
email: string;
metadata: unknown;
name: string;
preferences: { notifications: { email: boolean; push: boolean }; ui: { sidebarCollapsed: boolean; theme: string } };
settings: { language: string; notifications: boolean; theme: string };
tags: string[];
}
export interface ProfileCreateSuccessResponseBody {
meta?: Record<string, unknown>;
profile: Profile;
}
export interface ProfileIndexSuccessResponseBody {
meta?: Record<string, unknown>;
pagination: OffsetPagination;
profiles: Profile[];
}
export interface ProfilePage {
number?: number;
size?: number;
}
export interface ProfileShowSuccessResponseBody {
meta?: Record<string, unknown>;
profile: Profile;
}
export interface ProfileUpdatePayload {
addresses?: { city: string; primary: boolean; street: string; zip: string }[];
email?: string;
metadata?: unknown;
name?: string;
preferences?: { notifications: { email: boolean; push: boolean }; ui: { sidebarCollapsed: boolean; theme: string } };
settings?: { language: string; notifications: boolean; theme: string };
tags?: string[];
}
export interface ProfileUpdateSuccessResponseBody {
meta?: Record<string, unknown>;
profile: Profile;
}
export interface ProfilesCreateRequest {
body: ProfilesCreateRequestBody;
}
export interface ProfilesCreateRequestBody {
profile: ProfileCreatePayload;
}
export interface ProfilesCreateResponse {
body: ProfilesCreateResponseBody;
}
export type ProfilesCreateResponseBody = ErrorResponseBody | ProfileCreateSuccessResponseBody;
export type ProfilesDestroyResponse = never;
export interface ProfilesIndexRequest {
query: ProfilesIndexRequestQuery;
}
export interface ProfilesIndexRequestQuery {
page?: ProfilePage;
}
export interface ProfilesIndexResponse {
body: ProfilesIndexResponseBody;
}
export type ProfilesIndexResponseBody = ErrorResponseBody | ProfileIndexSuccessResponseBody;
export interface ProfilesShowResponse {
body: ProfilesShowResponseBody;
}
export type ProfilesShowResponseBody = ErrorResponseBody | ProfileShowSuccessResponseBody;
export interface ProfilesUpdateRequest {
body: ProfilesUpdateRequestBody;
}
export interface ProfilesUpdateRequestBody {
profile: ProfileUpdatePayload;
}
export interface ProfilesUpdateResponse {
body: ProfilesUpdateResponseBody;
}
export type ProfilesUpdateResponseBody = ErrorResponseBody | ProfileUpdateSuccessResponseBody;OpenAPI
yml
---
openapi: 3.1.0
info:
title: "/curious_cat"
version: 1.0.0
paths:
"/profiles":
get:
operationId: profilesIndex
parameters:
- in: query
name: page
required: false
schema:
"$ref": "#/components/schemas/profilePage"
responses:
'200':
content:
application/json:
schema:
"$ref": "#/components/schemas/profileIndexSuccessResponseBody"
description: Successful response
post:
operationId: profilesCreate
requestBody:
content:
application/json:
schema:
properties:
profile:
"$ref": "#/components/schemas/profileCreatePayload"
type: object
required:
- profile
required: true
responses:
'200':
content:
application/json:
schema:
"$ref": "#/components/schemas/profileCreateSuccessResponseBody"
description: Successful response
'422':
description: Unprocessable Entity
content:
application/json:
schema:
"$ref": "#/components/schemas/errorResponseBody"
"/profiles/{id}":
get:
operationId: profilesShow
parameters:
- in: path
name: id
required: true
schema:
type: string
responses:
'200':
content:
application/json:
schema:
"$ref": "#/components/schemas/profileShowSuccessResponseBody"
description: Successful response
patch:
operationId: profilesUpdate
parameters:
- in: path
name: id
required: true
schema:
type: string
requestBody:
content:
application/json:
schema:
properties:
profile:
"$ref": "#/components/schemas/profileUpdatePayload"
type: object
required:
- profile
required: true
responses:
'200':
content:
application/json:
schema:
"$ref": "#/components/schemas/profileUpdateSuccessResponseBody"
description: Successful response
'422':
description: Unprocessable Entity
content:
application/json:
schema:
"$ref": "#/components/schemas/errorResponseBody"
delete:
operationId: profilesDestroy
parameters:
- in: path
name: id
required: true
schema:
type: string
responses:
'204':
description: No content
components:
schemas:
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"
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
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
profile:
properties:
addresses:
items:
properties:
city:
type: string
primary:
type: boolean
street:
type: string
zip:
type: string
type: object
required:
- city
- primary
- street
- zip
type: array
createdAt:
type: string
format: date-time
email:
type: string
format: email
id:
type: string
metadata: {}
name:
type: string
preferences:
properties:
notifications:
properties:
email:
type: boolean
push:
type: boolean
type: object
required:
- email
- push
ui:
properties:
sidebarCollapsed:
type: boolean
theme:
type: string
type: object
required:
- sidebarCollapsed
- theme
type: object
required:
- notifications
- ui
settings:
properties:
language:
type: string
notifications:
type: boolean
theme:
type: string
type: object
required:
- language
- notifications
- theme
tags:
items:
type: string
type: array
updatedAt:
type: string
format: date-time
type: object
required:
- addresses
- createdAt
- email
- id
- metadata
- name
- preferences
- settings
- tags
- updatedAt
profileCreatePayload:
properties:
addresses:
items:
properties:
city:
type: string
primary:
type: boolean
street:
type: string
zip:
type: string
type: object
required:
- city
- primary
- street
- zip
type: array
email:
type: string
format: email
metadata: {}
name:
type: string
preferences:
properties:
notifications:
properties:
email:
type: boolean
push:
type: boolean
type: object
required:
- email
- push
ui:
properties:
sidebarCollapsed:
type: boolean
theme:
type: string
type: object
required:
- sidebarCollapsed
- theme
type: object
required:
- notifications
- ui
settings:
properties:
language:
type: string
notifications:
type: boolean
theme:
type: string
type: object
required:
- language
- notifications
- theme
tags:
items:
type: string
type: array
type: object
required:
- addresses
- email
- metadata
- name
- preferences
- settings
- tags
profileCreateSuccessResponseBody:
properties:
meta:
properties: {}
type: object
profile:
"$ref": "#/components/schemas/profile"
type: object
required:
- profile
profileIndexSuccessResponseBody:
properties:
pagination:
"$ref": "#/components/schemas/offsetPagination"
meta:
properties: {}
type: object
profiles:
items:
"$ref": "#/components/schemas/profile"
type: array
type: object
required:
- pagination
- profiles
profilePage:
properties:
number:
type: integer
minimum: 1
size:
type: integer
minimum: 1
maximum: 100
type: object
profileShowSuccessResponseBody:
properties:
meta:
properties: {}
type: object
profile:
"$ref": "#/components/schemas/profile"
type: object
required:
- profile
profileUpdatePayload:
properties:
addresses:
items:
properties:
city:
type: string
primary:
type: boolean
street:
type: string
zip:
type: string
type: object
required:
- city
- primary
- street
- zip
type: array
email:
type: string
format: email
metadata: {}
name:
type: string
preferences:
properties:
notifications:
properties:
email:
type: boolean
push:
type: boolean
type: object
required:
- email
- push
ui:
properties:
sidebarCollapsed:
type: boolean
theme:
type: string
type: object
required:
- sidebarCollapsed
- theme
type: object
required:
- notifications
- ui
settings:
properties:
language:
type: string
notifications:
type: boolean
theme:
type: string
type: object
required:
- language
- notifications
- theme
tags:
items:
type: string
type: array
type: object
profileUpdateSuccessResponseBody:
properties:
meta:
properties: {}
type: object
profile:
"$ref": "#/components/schemas/profile"
type: object
required:
- profile