openapi: 3.1.0 info: title: Food Express API description: > API for managing the FoodExpress restaurants, orders, and customers. version: 1.0.0 servers: - url: http://localhost:4004/api/v1 description: Local development servers - url: https://{stage}.foodexpress.com/api/v1 description: Stage server variables: stage: description: Stage enum: - dev - test default: dev - url: https://foodexpress.com/api/v1 description: Production server tags: - name: Restaurants - name: Orders - name: Customers paths: /restaurants: get: tags: [Restaurants] summary: List restaurants description: Retrieve a paginated list of restaurants. security: [] parameters: - $ref: "#/components/parameters/Limit" - $ref: "#/components/parameters/Offset" - $ref: "#/components/parameters/AcceptLanguage" responses: "200": description: A paginated list of restaurants content: application/json: schema: type: object properties: data: type: array items: $ref: "#/components/schemas/Restaurant" pagination: $ref: "#/components/schemas/Pagination" /restaurants/{id}/menu: get: tags: [Restaurants] summary: Get restaurant menu security: [] parameters: - $ref: "#/components/parameters/RestaurantId" - $ref: "#/components/parameters/AcceptLanguage" responses: "200": description: "Menu for the restaurant" content: application/json: schema: $ref: "#/components/schemas/Menu" "404": description: Restaurant not found /restaurants/{id}/orders: get: tags: [Orders, Restaurants] summary: List orders for a restaurant description: Retrieve a paginated list of orders for a specific restaurant. parameters: - $ref: "#/components/parameters/RestaurantId" - $ref: "#/components/parameters/Limit" - $ref: "#/components/parameters/Offset" responses: "200": description: A paginated list of orders content: application/json: schema: type: object properties: data: type: array items: $ref: "#/components/schemas/Order" pagination: $ref: "#/components/schemas/Pagination" /orders: post: tags: [Orders] summary: Create a new order requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/CreateOrderRequest" parameters: - $ref: "#/components/parameters/IdempotencyKey" responses: "201": description: Order created content: application/json: schema: $ref: "#/components/schemas/Order" "400": description: Invalid request /orders/{orderId}: get: tags: [Orders] summary: Get order by ID parameters: - $ref: "#/components/parameters/OrderId" responses: "200": description: Order details content: application/json: schema: $ref: "#/components/schemas/Order" "404": description: Order not found /orders/{orderId}/status: patch: tags: [Orders] summary: Update order status description: Update the status of an existing order. parameters: - $ref: "#/components/parameters/OrderId" requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/UpdateOrderStatusRequest" responses: "200": description: Order status updated content: application/json: schema: $ref: "#/components/schemas/Order" "409": description: Invalid status transition /customers: post: tags: [Customers] summary: Create a customer requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/CreateCustomerRequest" examples: Customer: $ref: "#/components/examples/CustomerRequest" parameters: - $ref: "#/components/parameters/IdempotencyKey" responses: "201": description: Customer created content: application/json: schema: $ref: "#/components/schemas/Customer" /customers/me: get: tags: [Customers] summary: Get current customer description: Returns the authenticated customer's profile responses: "200": $ref: "#/components/responses/CustomerDetails" /customers/{id}: get: tags: [Customers] summary: Get customer by ID parameters: - $ref: "#/components/parameters/CustomerId" responses: "200": $ref: "#/components/responses/CustomerDetails" "404": description: Customer not found patch: tags: [Customers] summary: Update customer details parameters: - $ref: "#/components/parameters/CustomerId" requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/UpdateCustomerRequest" examples: Customer: $ref: "#/components/examples/CustomerRequest" responses: "200": description: Customer updated content: application/json: schema: $ref: "#/components/schemas/Customer" delete: tags: [Customers] summary: Delete customer parameters: - $ref: "#/components/parameters/CustomerId" responses: "204": description: Customer deleted components: parameters: RestaurantId: name: id in: path required: true schema: type: string example: "09ede9cb-0031-4469-9144-dec6b564f1c0" OrderId: name: orderId in: path required: true schema: type: string example: "e17aca0c-c956-4a0d-afec-b117a9926e2c" CustomerId: name: id in: path required: true schema: type: string example: "18e1d8a2-e7ca-458f-a997-2cc80754105f" Limit: name: limit in: query schema: type: integer minimum: 1 maximum: 100 default: 20 examples: [20] Offset: name: offset in: query schema: type: integer minimum: 0 default: 0 examples: [0] IdempotencyKey: in: header name: Idempotency-Key required: false description: Unique key to prevent duplicate orders schema: type: string AcceptLanguage: in: header name: Accept-Language required: false description: Preferred language for localized strings. schema: type: string example: "de-DE" schemas: Restaurant: type: object properties: id: type: string examples: ["465db18f-6fc0-48e1-804a-156d0df29392"] name: type: string examples: ["Thai Food"] address: type: string examples: ["Hauptstraße 9, 68259 Mannheim"] Menu: type: array items: $ref: "#/components/schemas/MenuItem" MenuItem: type: object properties: id: type: string examples: ["9f062baf-236b-44fe-8d30-88cecb02c26b"] name: type: string examples: ["Cheeseburger"] price: type: number examples: [3.99] Order: type: object properties: id: type: string examples: ["28c0bc0d-9d17-4b74-9885-84a4cd7c761e"] restaurantId: type: string examples: ["73591883-8aa4-4a2d-a411-abf42220a824"] customerId: type: string examples: ["706f645d-a420-4984-a913-c9a6e0c677f2"] status: $ref: "#/components/schemas/OrderStatus" items: type: array items: $ref: "#/components/schemas/OrderItem" totalAmount: type: number examples: [29.95] OrderItem: type: object properties: menuItemId: type: string examples: ["359d9b4a-c8a2-4457-a04a-fecddadad64f"] quantity: type: integer minimum: 1 examples: [1] OrderStatus: type: string enum: - CREATED - CONFIRMED - PREPARING - READY - DELIVERED - CANCELLED examples: ["CREATED"] CreateOrderRequest: type: object required: [restaurantId, customerId, items] properties: restaurantId: type: string examples: ["435cb941-3483-4e80-acc1-6454f1f948b5"] customerId: type: string examples: ["433569a1-d4d8-4073-ab1a-d26339c747c3"] items: type: array items: $ref: "#/components/schemas/OrderItem" UpdateOrderStatusRequest: type: object required: [status] properties: status: $ref: "#/components/schemas/OrderStatus" Customer: type: object properties: id: type: string examples: ["1a7830a6-8e0f-43b2-a0e0-4479cb0acf7d"] name: type: string examples: ["Max Mustermann"] email: type: string examples: ["max.mustermann@gmail.com"] CreateCustomerRequest: type: object required: [name, email] properties: name: type: string email: type: string UpdateCustomerRequest: type: object properties: name: type: string email: type: string Pagination: type: object properties: limit: type: integer examples: [20] offset: type: integer examples: [0] total: type: integer examples: [35] responses: CustomerDetails: description: "Customer details" content: application/json: schema: $ref: "#/components/schemas/Customer" examples: CustomerRequest: value: name: "Max Mustermann" email: "max.mustermann@gmail.com" securitySchemes: BasicAuth: type: http scheme: basic ApiKeyAuth: type: apiKey in: header name: X-API-Key security: - BasicAuth: []