Skip to content

E-Commerce API

A comprehensive e-commerce API demonstrating advanced Soxom features.

  • Nested resources (users → settings)
  • Union types with discriminator (PaymentMethod)
  • Schema composition with allOf
  • Multiple authentication methods
  • Cursor and offset pagination
  • Custom timeouts and retry configuration
soxom.yaml
version: "1.0"
sdk:
name: acme-store-sdk
version: 1.0.0
description: SDK for Acme Store API
spec:
path: ./openapi.yaml
targets:
typescript:
package_name: "@acme/store-sdk"
python:
package_name: acme-store-sdk
resources:
users:
models:
- User
- UserCreate
methods:
list: get /users
create: post /users
get: get /users/{user_id}
update: put /users/{user_id}
subresources:
settings:
models:
- UserSettings
methods:
get: get /users/{user_id}/settings
update: put /users/{user_id}/settings
products:
models:
- Product
- ProductCreate
methods:
list: get /products
create: post /products
get: get /products/{product_id}
orders:
models:
- Order
- OrderCreate
methods:
list: get /orders
create: post /orders
get: get /orders/{order_id}
cancel: post /orders/{order_id}/cancel
payments:
models:
- Payment
- PaymentMethod
- CreditCard
- BankAccount
methods:
create: post /payments
get: get /payments/{payment_id}
pagination:
default_type: cursor
schemes:
cursor:
cursor:
request_param: after
response_property: next_cursor
limit:
request_param: limit
default: 20
max: 100
has_more:
response_property: has_more
offset:
offset:
request_param: offset
limit:
request_param: limit
default: 20
total:
response_property: total
authentication:
default: bearer
env_vars:
bearer:
token: ACME_API_TOKEN
retries:
enabled: true
max_attempts: 3
timeouts:
default_ms: 60000
operations:
orders_create:
default_ms: 30000
components:
schemas:
PaymentMethod:
oneOf:
- $ref: '#/components/schemas/CreditCard'
- $ref: '#/components/schemas/BankAccount'
discriminator:
propertyName: type
mapping:
credit_card: '#/components/schemas/CreditCard'
bank_account: '#/components/schemas/BankAccount'
CreditCard:
type: object
required:
- type
- card_number
- expiry_month
- expiry_year
properties:
type:
type: string
enum: [credit_card]
card_number:
type: string
expiry_month:
type: integer
expiry_year:
type: integer
cardholder_name:
type: string
BankAccount:
type: object
required:
- type
- account_number
- routing_number
properties:
type:
type: string
enum: [bank_account]
account_number:
type: string
routing_number:
type: string
components:
schemas:
TimestampedResource:
type: object
properties:
created_at:
type: string
format: date-time
updated_at:
type: string
format: date-time
User:
allOf:
- $ref: '#/components/schemas/TimestampedResource'
- type: object
required:
- id
- email
- name
properties:
id:
type: string
email:
type: string
name:
type: string
status:
type: string
enum: [active, inactive]
import { AcmeStoreClient } from '@acme/store-sdk';
const client = new AcmeStoreClient({
token: process.env.ACME_API_TOKEN
});
// List users with pagination
for await (const user of client.users.list()) {
console.log(`${user.name} - ${user.email}`);
}
// Get user
const user = await client.users.get("user-123");
// Nested resource: user settings
const settings = await client.users.settings.get("user-123");
console.log(`Theme: ${settings.theme}`);
// Update settings
await client.users.settings.update("user-123", {
theme: "dark",
notifications_enabled: true
});
// Products use offset pagination
const page1 = await client.products.list({ limit: 10 });
console.log(`Total products: ${page1.total}`);
// Get next page
const page2 = await client.products.list({
offset: 10,
limit: 10
});
// Create order
const order = await client.orders.create({
items: [
{ product_id: "prod-123", quantity: 2 },
{ product_id: "prod-456", quantity: 1 }
],
shipping_address: {
street: "123 Main St",
city: "San Francisco",
country: "US"
}
});
console.log(`Order ${order.id}: $${order.total}`);
// Cancel order
const cancelled = await client.orders.cancel(order.id);
console.log(`Status: ${cancelled.status}`); // "cancelled"
// Pay with credit card
const payment = await client.payments.create({
amount: 99.99,
currency: "USD",
order_id: "order-123",
payment_method: {
type: "credit_card",
card_number: "4111111111111111",
expiry_month: 12,
expiry_year: 2025,
cardholder_name: "John Doe"
}
});
// Pay with bank account
const bankPayment = await client.payments.create({
amount: 500.00,
currency: "USD",
order_id: "order-456",
payment_method: {
type: "bank_account",
account_number: "123456789",
routing_number: "021000021"
}
});
// Type narrowing works
const pm = payment.payment_method;
if (pm.type === "credit_card") {
console.log(`Card: **** ${pm.card_number.slice(-4)}`);
} else {
console.log(`Bank: ${pm.account_number}`);
}