From 7e72d8e064a1a5a8728a623627db39b256812ea2 Mon Sep 17 00:00:00 2001 From: Phil Sturgeon <67381+philsturgeon@users.noreply.github.com> Date: Thu, 21 Nov 2024 21:50:28 +0000 Subject: [PATCH] revert main openapi.yaml and make a overlay / generated openapi.mock.yaml --- .microcks/openapi.mock.yaml | 1216 +++++++++++++++++++++++++++++++++++ .microcks/overlays.yaml | 204 ++++++ openapi.yaml | 221 +++---- 3 files changed, 1508 insertions(+), 133 deletions(-) create mode 100644 .microcks/openapi.mock.yaml create mode 100644 .microcks/overlays.yaml diff --git a/.microcks/openapi.mock.yaml b/.microcks/openapi.mock.yaml new file mode 100644 index 0000000..fdeb438 --- /dev/null +++ b/.microcks/openapi.mock.yaml @@ -0,0 +1,1216 @@ +openapi: 3.1.0 +info: + title: Train Travel API + description: | + API for finding and booking train trips across Europe. + + ## Run in Postman + + Experiment with this API in Postman, using our Postman Collection. + + [Run In Postman](https://app.getpostman.com/run-collection/9265903-7a75a0d0-b108-4436-ba54-c6139698dc08?action=collection%2Ffork&source=rip_markdown&collection-url=entityId%3D9265903-7a75a0d0-b108-4436-ba54-c6139698dc08%26entityType%3Dcollection%26workspaceId%3Df507f69d-9564-419c-89a2-cb8e4c8c7b8f) + version: 1.0.0 + contact: + name: Train Support + url: https://example.com/support + email: support@example.com + license: + name: Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International + identifier: CC-BY-NC-SA-4.0 + x-feedbackLink: + label: Submit Feedback + url: https://github.com/bump-sh-examples/train-travel-api/issues/new +servers: + - url: https://api.example.com + description: Production + x-internal: false + - url: https://mocks.example.com/rest + description: Mock Server + x-internal: false +security: + - OAuth2: + - read +tags: + - name: Stations + description: | + Find and filter train stations across Europe, including their location + and local timezone. + - name: Trips + description: | + Timetables and routes for train trips between stations, including pricing + and availability. + - name: Bookings + description: | + Create and manage bookings for train trips, including passenger details + and optional extras. + - name: Payments + description: "Pay for bookings using a card or bank account, and view payment\nstatus and history.\n\n> warn\n> Bookings usually expire within 1 hour so you'll need to make your payment\n> before the expiry date \n" +paths: + /stations: + get: + summary: Get a list of train stations + description: Returns a paginated and searchable list of all train stations. + operationId: get-stations + tags: + - Stations + parameters: + - $ref: '#/components/parameters/page' + - $ref: '#/components/parameters/limit' + - name: coordinates + in: query + description: > + The latitude and longitude of the user's location, to narrow down the search results to sites within a proximity of this location. + + required: false + schema: + type: string + example: 52.5200,13.4050 + - name: search + in: query + description: > + A search term to filter the list of stations by name or address. + + required: false + schema: + type: string + examples: + - Milano Centrale + - Paris + - name: country + in: query + description: Filter stations by country code + required: false + schema: + type: string + format: iso-country-code + example: DE + responses: + '200': + description: OK + headers: + Cache-Control: + $ref: '#/components/headers/Cache-Control' + RateLimit: + $ref: '#/components/headers/RateLimit' + content: + application/json: + schema: + type: object + properties: + data: + type: array + items: + $ref: '#/components/schemas/Station' + examples: + stations: + summary: A list of train stations + value: + data: + - id: efdbb9d1-02c2-4bc3-afb7-6788d8782b1e + name: Berlin Hauptbahnhof + address: Invalidenstraße 10557 Berlin, Germany + country_code: DE + timezone: Europe/Berlin + - id: b2e783e1-c824-4d63-b37a-d8d698862f1d + name: Paris Gare du Nord + address: 18 Rue de Dunkerque 75010 Paris, France + country_code: FR + timezone: Europe/Paris + links: + self: https://api.example.com/stations&page=2 + next: https://api.example.com/stations?page=3 + prev: https://api.example.com/stations?page=1 + application/xml: + schema: + allOf: + - $ref: '#/components/schemas/Wrapper-Collection' + - properties: + data: + type: array + xml: + name: stations + wrapped: true + items: + $ref: '#/components/schemas/Station' + - properties: + links: + allOf: + - $ref: '#/components/schemas/Links-Self' + - $ref: '#/components/schemas/Links-Pagination' + '400': + $ref: '#/components/responses/BadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + '403': + $ref: '#/components/responses/Forbidden' + '429': + $ref: '#/components/responses/TooManyRequests' + '500': + $ref: '#/components/responses/InternalServerError' + /trips: + get: + summary: Get available train trips + description: > + Returns a list of available train trips between the specified origin and destination stations on the given date, and allows for filtering by bicycle and dog allowances. + + operationId: get-trips + tags: + - Trips + parameters: + - $ref: '#/components/parameters/page' + - $ref: '#/components/parameters/limit' + - name: origin + in: query + description: The ID of the origin station + required: true + schema: + type: string + format: uuid + examples: + trips: + value: b2e783e1-c824-4d63-b37a-d8d698862f1d + - name: destination + in: query + description: The ID of the destination station + required: true + schema: + type: string + format: uuid + examples: + trips: + value: '2024-02-01T09:00:00Z' + - name: date + in: query + description: The date and time of the trip in ISO 8601 format in origin station's timezone. + required: true + schema: + type: string + format: date-time + example: '2024-02-01T09:00:00Z' + - name: bicycles + in: query + description: Only return trips where bicycles are known to be allowed + required: false + schema: + type: boolean + default: false + - name: dogs + in: query + description: Only return trips where dogs are known to be allowed + required: false + schema: + type: boolean + default: false + responses: + '200': + description: A list of available train trips + headers: + Cache-Control: + $ref: '#/components/headers/Cache-Control' + RateLimit: + $ref: '#/components/headers/RateLimit' + content: + application/json: + schema: + allOf: + - $ref: '#/components/schemas/Wrapper-Collection' + - properties: + data: + type: array + items: + $ref: '#/components/schemas/Trip' + - properties: + links: + allOf: + - $ref: '#/components/schemas/Links-Self' + - $ref: '#/components/schemas/Links-Pagination' + examples: + trips: + summary: A list of available train trips + value: + data: + - id: ea399ba1-6d95-433f-92d1-83f67b775594 + origin: efdbb9d1-02c2-4bc3-afb7-6788d8782b1e + destination: b2e783e1-c824-4d63-b37a-d8d698862f1d + departure_time: '2024-02-01T10:00:00Z' + arrival_time: '2024-02-01T16:00:00Z' + price: 50 + operator: Deutsche Bahn + bicycles_allowed: true + dogs_allowed: true + - id: 4d67459c-af07-40bb-bb12-178dbb88e09f + origin: b2e783e1-c824-4d63-b37a-d8d698862f1d + destination: efdbb9d1-02c2-4bc3-afb7-6788d8782b1e + departure_time: '2024-02-01T12:00:00Z' + arrival_time: '2024-02-01T18:00:00Z' + price: 50 + operator: SNCF + bicycles_allowed: true + dogs_allowed: true + links: + self: https://api.example.com/trips?origin=efdbb9d1-02c2-4bc3-afb7-6788d8782b1e&destination=b2e783e1-c824-4d63-b37a-d8d698862f1d&date=2024-02-01 + next: https://api.example.com/trips?origin=efdbb9d1-02c2-4bc3-afb7-6788d8782b1e&destination=b2e783e1-c824-4d63-b37a-d8d698862f1d&date=2024-02-01&page=2 + application/xml: + schema: + allOf: + - $ref: '#/components/schemas/Wrapper-Collection' + - properties: + data: + type: array + xml: + name: trips + wrapped: true + items: + $ref: '#/components/schemas/Trip' + - properties: + links: + allOf: + - $ref: '#/components/schemas/Links-Self' + - $ref: '#/components/schemas/Links-Pagination' + '400': + $ref: '#/components/responses/BadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + '403': + $ref: '#/components/responses/Forbidden' + '429': + $ref: '#/components/responses/TooManyRequests' + '500': + $ref: '#/components/responses/InternalServerError' + /bookings: + get: + operationId: get-bookings + summary: List existing bookings + description: Returns a list of all trip bookings by the authenticated user. + tags: + - Bookings + parameters: + - $ref: '#/components/parameters/page' + - $ref: '#/components/parameters/limit' + responses: + '200': + description: A list of bookings + headers: + Cache-Control: + $ref: '#/components/headers/Cache-Control' + RateLimit: + $ref: '#/components/headers/RateLimit' + content: + application/json: + schema: + allOf: + - $ref: '#/components/schemas/Wrapper-Collection' + - properties: + data: + type: array + items: + $ref: '#/components/schemas/Booking' + - properties: + links: + allOf: + - $ref: '#/components/schemas/Links-Self' + - $ref: '#/components/schemas/Links-Pagination' + examples: + bookings: + summary: A list of bookings + value: + data: + - id: bfc5af2c-f477-43c4-8bdf-a00bdb939d65 + trip_id: efdbb9d1-02c2-4bc3-afb7-6788d8782b1e + passenger_name: John Doe + has_bicycle: true + has_dog: true + - id: 1725ff48-ab45-4bb5-9d02-88745177dedb + trip_id: b2e783e1-c824-4d63-b37a-d8d698862f1d + passenger_name: Jane Smith + has_bicycle: false + has_dog: false + links: + self: https://api.example.com/bookings + next: https://api.example.com/bookings?page=2 + application/xml: + schema: + allOf: + - $ref: '#/components/schemas/Wrapper-Collection' + - properties: + data: + type: array + xml: + name: bookings + wrapped: true + items: + $ref: '#/components/schemas/Booking' + - properties: + links: + allOf: + - $ref: '#/components/schemas/Links-Self' + - $ref: '#/components/schemas/Links-Pagination' + '400': + $ref: '#/components/responses/BadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + '403': + $ref: '#/components/responses/Forbidden' + '429': + $ref: '#/components/responses/TooManyRequests' + '500': + $ref: '#/components/responses/InternalServerError' + post: + operationId: create-booking + summary: Create a booking + description: A booking is a temporary hold on a trip. It is not confirmed until the payment is processed. + tags: + - Bookings + security: + - OAuth2: + - write + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/Booking' + application/xml: + schema: + $ref: '#/components/schemas/Booking' + responses: + '201': + description: Booking successful + content: + application/json: + schema: + allOf: + - $ref: '#/components/schemas/Booking' + - properties: + links: + $ref: '#/components/schemas/Links-Self' + examples: + new_booking: + summary: New Booking + value: |- + { + "id": "{{ uuid() > put(bookingId) }}", + "trip_id": "{{ request.body/trip_id }}", + "passenger_name": "{{ request.body/passenger_name }}", + "has_bicycle": {{ request.body/has_bicycle }}, + "has_dog": {{ request.body/has_dog }}, + "links": { + "self": "https://api.example.com/bookings/{{ bookingId }}" + } + } + application/xml: + schema: + allOf: + - $ref: '#/components/schemas/Booking' + - properties: + links: + $ref: '#/components/schemas/Links-Self' + '400': + $ref: '#/components/responses/BadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + '404': + $ref: '#/components/responses/NotFound' + '409': + $ref: '#/components/responses/Conflict' + '429': + $ref: '#/components/responses/TooManyRequests' + '500': + $ref: '#/components/responses/InternalServerError' + /bookings/{bookingId}: + parameters: + - name: bookingId + in: path + required: true + description: The ID of the booking to retrieve. + schema: + type: string + format: uuid + examples: + booking_1725ff48-ab45-4bb5-9d02-88745177dedb: + value: 1725ff48-ab45-4bb5-9d02-88745177dedb + booking_bfc5af2c-f477-43c4-8bdf-a00bdb939d65: + value: bfc5af2c-f477-43c4-8bdf-a00bdb939d65 + get: + summary: Get a booking + description: Returns the details of a specific booking. + operationId: get-booking + tags: + - Bookings + responses: + '200': + description: The booking details + headers: + Cache-Control: + $ref: '#/components/headers/Cache-Control' + RateLimit: + $ref: '#/components/headers/RateLimit' + content: + application/json: + schema: + allOf: + - $ref: '#/components/schemas/Booking' + - properties: + links: + $ref: '#/components/schemas/Links-Self' + examples: + booking_1725ff48-ab45-4bb5-9d02-88745177dedb: + summary: John Doe + value: + id: 1725ff48-ab45-4bb5-9d02-88745177dedb + trip_id: efdbb9d1-02c2-4bc3-afb7-6788d8782b1e + passenger_name: John Doe + has_bicycle: true + has_dog: true + links: + self: https://api.example.com/bookings/1725ff48-ab45-4bb5-9d02-88745177dedb + booking_bfc5af2c-f477-43c4-8bdf-a00bdb939d65: + summary: Billy Bikeless + value: + id: bfc5af2c-f477-43c4-8bdf-a00bdb939d65 + trip_id: efdbb9d1-02c2-4bc3-afb7-6788d8782b1e + passenger_name: Billy Bikeless + has_bicycle: false + has_dog: true + links: + self: https://api.example.com/bookings/1725ff48-ab45-4bb5-9d02-88745177dedb + application/xml: + schema: + allOf: + - $ref: '#/components/schemas/Booking' + - properties: + links: + $ref: '#/components/schemas/Links-Self' + '400': + $ref: '#/components/responses/BadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + '403': + $ref: '#/components/responses/Forbidden' + '404': + $ref: '#/components/responses/NotFound' + '429': + $ref: '#/components/responses/TooManyRequests' + '500': + $ref: '#/components/responses/InternalServerError' + delete: + summary: Delete a booking + description: Deletes a booking, cancelling the hold on the trip. + operationId: delete-booking + security: + - OAuth2: + - write + tags: + - Bookings + responses: + '204': + description: Booking deleted + '400': + $ref: '#/components/responses/BadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + '403': + $ref: '#/components/responses/Forbidden' + '404': + $ref: '#/components/responses/NotFound' + '429': + $ref: '#/components/responses/TooManyRequests' + '500': + $ref: '#/components/responses/InternalServerError' + /bookings/{bookingId}/payment: + parameters: + - name: bookingId + in: path + required: true + description: The ID of the booking to pay for. + schema: + type: string + format: uuid + examples: + Card: + value: 1725ff48-ab45-4bb5-9d02-88745177dedb + Bank: + value: 1725ff48-ab45-4bb5-9d02-88745177dedb + post: + summary: Pay for a Booking + description: A payment is an attempt to pay for the booking, which will confirm the booking for the user and enable them to get their tickets. + operationId: create-booking-payment + tags: + - Payments + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/BookingPayment' + examples: + Card: + summary: Card Payment + value: + amount: 49.99 + currency: gbp + source: + object: card + name: J. Doe + number: '4242424242424242' + cvc: 123 + exp_month: 12 + exp_year: 2025 + address_line1: 123 Fake Street + address_line2: 4th Floor + address_city: London + address_country: gb + address_post_code: N12 9XX + Bank: + summary: Bank Account Payment + value: + amount: 100.5 + currency: gbp + source: + object: bank_account + name: J. Doe + number: '00012345' + sort_code: '000123' + account_type: individual + bank_name: Starling Bank + country: gb + responses: + '200': + description: Payment successful + headers: + Cache-Control: + $ref: '#/components/headers/Cache-Control' + RateLimit: + $ref: '#/components/headers/RateLimit' + content: + application/json: + schema: + allOf: + - $ref: '#/components/schemas/BookingPayment' + - properties: + links: + $ref: '#/components/schemas/Links-Booking' + examples: + Card: + summary: Card Payment + value: + id: 2e3b4f5a-6b7c-8d9e-0f1a-2b3c4d5e6f7a + amount: 49.99 + currency: gbp + source: + object: card + name: J. Doe + number: '************4242' + cvc: 123 + exp_month: 12 + exp_year: 2025 + address_country: gb + address_post_code: N12 9XX + status: succeeded + links: + booking: https://api.example.com/bookings/1725ff48-ab45-4bb5-9d02-88745177dedb/payment + Bank: + summary: Bank Account Payment + value: + id: 2e3b4f5a-6b7c-8d9e-0f1a-2b3c4d5e6f7a + amount: 100.5 + currency: gbp + source: + object: bank_account + name: J. Doe + account_type: individual + number: '*********2345' + sort_code: '000123' + bank_name: Starling Bank + country: gb + status: succeeded + links: + booking: https://api.example.com/bookings/1725ff48-ab45-4bb5-9d02-88745177dedb + '400': + $ref: '#/components/responses/BadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + '403': + $ref: '#/components/responses/Forbidden' + '429': + $ref: '#/components/responses/TooManyRequests' + '500': + $ref: '#/components/responses/InternalServerError' +webhooks: + newBooking: + post: + operationId: new-booking + summary: New Booking + description: | + Subscribe to new bookings being created, to update integrations for your users. Related data is available via the links provided in the request. + tags: + - Bookings + requestBody: + content: + application/json: + schema: + allOf: + - $ref: '#/components/schemas/Booking' + - properties: + links: + allOf: + - $ref: '#/components/schemas/Links-Self' + - $ref: '#/components/schemas/Links-Pagination' + examples: + new_booking: + summary: New Booking + value: + id: efdbb9d1-02c2-4bc3-afb7-6788d8782b1e + trip_id: efdbb9d1-02c2-4bc3-afb7-6788d8782b1e + passenger_name: John Doe + has_bicycle: true + has_dog: true + links: + self: https://api.example.com/bookings/1725ff48-ab45-4bb5-9d02-88745177dedb + responses: + '200': + description: Return a 200 status to indicate that the data was received successfully. +components: + parameters: + page: + name: page + in: query + description: The page number to return + required: false + schema: + type: integer + minimum: 1 + default: 1 + example: 1 + limit: + name: limit + in: query + description: The number of items to return per page + required: false + schema: + type: integer + minimum: 1 + maximum: 100 + default: 10 + example: 10 + securitySchemes: + OAuth2: + type: oauth2 + description: OAuth 2.0 authorization code following RFC8725 best practices. + flows: + authorizationCode: + authorizationUrl: https://example.com/oauth/authorize + tokenUrl: https://example.com/oauth/token + scopes: + read: Read access + write: Write access + schemas: + Station: + type: object + xml: + name: station + required: + - id + - name + - address + - country_code + properties: + id: + type: string + format: uuid + description: Unique identifier for the station. + examples: + - efdbb9d1-02c2-4bc3-afb7-6788d8782b1e + - b2e783e1-c824-4d63-b37a-d8d698862f1d + name: + type: string + description: The name of the station + examples: + - Berlin Hauptbahnhof + - Paris Gare du Nord + address: + type: string + description: The address of the station. + examples: + - Invalidenstraße 10557 Berlin, Germany + - 18 Rue de Dunkerque 75010 Paris, France + country_code: + type: string + description: The country code of the station. + format: iso-country-code + examples: + - DE + - FR + timezone: + type: string + description: The timezone of the station in the [IANA Time Zone Database format](https://www.iana.org/time-zones). + examples: + - Europe/Berlin + - Europe/Paris + Links-Self: + type: object + properties: + self: + type: string + format: uri + Links-Pagination: + type: object + properties: + next: + type: string + format: uri + prev: + type: string + format: uri + Problem: + type: object + xml: + name: problem + namespace: urn:ietf:rfc:7807 + properties: + type: + type: string + description: A URI reference that identifies the problem type + examples: + - https://example.com/probs/out-of-credit + title: + type: string + description: A short, human-readable summary of the problem type + examples: + - You do not have enough credit. + detail: + type: string + description: A human-readable explanation specific to this occurrence of the problem + examples: + - Your current balance is 30, but that costs 50. + instance: + type: string + description: A URI reference that identifies the specific occurrence of the problem + examples: + - /account/12345/msgs/abc + status: + type: integer + description: The HTTP status code + examples: + - 400 + Trip: + type: object + xml: + name: trip + properties: + id: + type: string + format: uuid + description: Unique identifier for the trip + examples: + - 4f4e4e1-c824-4d63-b37a-d8d698862f1d + origin: + type: string + description: The starting station of the trip + examples: + - Berlin Hauptbahnhof + - Paris Gare du Nord + destination: + type: string + description: The destination station of the trip + examples: + - Paris Gare du Nord + - Berlin Hauptbahnhof + departure_time: + type: string + format: date-time + description: The date and time when the trip departs + examples: + - '2024-02-01T10:00:00Z' + arrival_time: + type: string + format: date-time + description: The date and time when the trip arrives + examples: + - '2024-02-01T16:00:00Z' + operator: + type: string + description: The name of the operator of the trip + examples: + - Deutsche Bahn + - SNCF + price: + type: number + description: The cost of the trip + examples: + - 50 + bicycles_allowed: + type: boolean + description: Indicates whether bicycles are allowed on the trip + dogs_allowed: + type: boolean + description: Indicates whether dogs are allowed on the trip + Booking: + type: object + xml: + name: booking + properties: + id: + type: string + format: uuid + description: Unique identifier for the booking + readOnly: true + examples: + - 3f3e3e1-c824-4d63-b37a-d8d698862f1d + trip_id: + type: string + format: uuid + description: Identifier of the booked trip + examples: + - 4f4e4e1-c824-4d63-b37a-d8d698862f1d + passenger_name: + type: string + description: Name of the passenger + examples: + - John Doe + has_bicycle: + type: boolean + description: Indicates whether the passenger has a bicycle. + has_dog: + type: boolean + description: Indicates whether the passenger has a dog. + Wrapper-Collection: + description: This is a generic request/response wrapper which contains both data and links which serve as hypermedia controls (HATEOAS). + type: object + properties: + data: + description: The wrapper for a collection is an array of objects. + type: array + items: + type: object + links: + description: A set of hypermedia links which serve as controls for the client. + type: object + readOnly: true + xml: + name: data + BookingPayment: + type: object + properties: + id: + description: Unique identifier for the payment. This will be a unique identifier for the payment, and is used to reference the payment in other objects. + type: string + format: uuid + readOnly: true + amount: + description: Amount intended to be collected by this payment. A positive decimal figure describing the amount to be collected. + type: number + exclusiveMinimum: 0 + examples: + - 49.99 + currency: + description: Three-letter [ISO currency code](https://www.iso.org/iso-4217-currency-codes.html), in lowercase. + type: string + enum: + - bam + - bgn + - chf + - eur + - gbp + - nok + - sek + - try + source: + unevaluatedProperties: false + description: The payment source to take the payment from. This can be a card or a bank account. Some of these properties will be hidden on read to protect PII leaking. + oneOf: + - title: Card + description: A card (debit or credit) to take payment from. + type: object + properties: + object: + type: string + const: card + name: + type: string + description: Cardholder's full name as it appears on the card. + examples: + - Francis Bourgeois + number: + type: string + description: The card number, as a string without any separators. On read all but the last four digits will be masked for security. + examples: + - '4242424242424242' + cvc: + type: integer + description: Card security code, 3 or 4 digits usually found on the back of the card. + minLength: 3 + maxLength: 4 + writeOnly: true + example: 123 + exp_month: + type: integer + format: int64 + description: Two-digit number representing the card's expiration month. + examples: + - 12 + exp_year: + type: integer + format: int64 + description: Four-digit number representing the card's expiration year. + examples: + - 2025 + address_line1: + type: string + writeOnly: true + address_line2: + type: string + writeOnly: true + address_city: + type: string + address_country: + type: string + address_post_code: + type: string + required: + - name + - number + - cvc + - exp_month + - exp_year + - address_country + - title: Bank Account + description: A bank account to take payment from. Must be able to make payments in the currency specified in the payment. + type: object + properties: + object: + const: bank_account + type: string + name: + type: string + number: + type: string + description: The account number for the bank account, in string form. Must be a current account. + sort_code: + type: string + description: The sort code for the bank account, in string form. Must be a six-digit number. + account_type: + enum: + - individual + - company + type: string + description: The type of entity that holds the account. This can be either `individual` or `company`. + bank_name: + type: string + description: The name of the bank associated with the routing number. + examples: + - Starling Bank + country: + type: string + description: Two-letter country code (ISO 3166-1 alpha-2). + required: + - name + - number + - account_type + - bank_name + - country + status: + description: The status of the payment, one of `pending`, `succeeded`, or `failed`. + type: string + enum: + - pending + - succeeded + - failed + readOnly: true + Links-Booking: + type: object + properties: + booking: + type: string + format: uri + examples: + - https://api.example.com/bookings/1725ff48-ab45-4bb5-9d02-88745177dedb + headers: + Cache-Control: + description: "The Cache-Control header communicates directives for caching mechanisms in both requests and responses. \nIt is used to specify the caching directives in responses to prevent caches from storing sensitive information.\n" + schema: + type: string + description: A comma-separated list of directives as defined in [RFC 9111](https://www.rfc-editor.org/rfc/rfc9111.html). + examples: + - max-age=3600 + - max-age=604800, public + - no-store + - no-cache + - private + RateLimit: + description: | + The RateLimit header communicates quota policies. It contains a `limit` to + convey the expiring limit, `remaining` to convey the remaining quota units, + and `reset` to convey the time window reset time. + schema: + type: string + examples: + - limit=10, remaining=0, reset=10 + Retry-After: + description: "The Retry-After header indicates how long the user agent should wait before making a follow-up request. \nThe value is in seconds and can be an integer or a date in the future. \nIf the value is an integer, it indicates the number of seconds to wait. \nIf the value is a date, it indicates the time at which the user agent should make a follow-up request. \n" + schema: + type: string + examples: + integer: + value: '120' + summary: Retry after 120 seconds + date: + value: 'Fri, 31 Dec 2021 23:59:59 GMT' + summary: Retry after the specified date + responses: + BadRequest: + description: Bad Request + headers: + RateLimit: + $ref: '#/components/headers/RateLimit' + content: + application/problem+json: + schema: + $ref: '#/components/schemas/Problem' + example: + type: https://example.com/errors/bad-request + title: Bad Request + status: 400 + detail: The request is invalid or missing required parameters. + application/problem+xml: + schema: + $ref: '#/components/schemas/Problem' + example: + type: https://example.com/errors/bad-request + title: Bad Request + status: 400 + detail: The request is invalid or missing required parameters. + Conflict: + description: Conflict + headers: + RateLimit: + $ref: '#/components/headers/RateLimit' + content: + application/problem+json: + schema: + $ref: '#/components/schemas/Problem' + example: + type: https://example.com/errors/conflict + title: Conflict + status: 409 + detail: There is a conflict with an existing resource. + application/problem+xml: + schema: + $ref: '#/components/schemas/Problem' + example: + type: https://example.com/errors/conflict + title: Conflict + status: 409 + detail: There is a conflict with an existing resource. + Forbidden: + description: Forbidden + headers: + RateLimit: + $ref: '#/components/headers/RateLimit' + content: + application/problem+json: + schema: + $ref: '#/components/schemas/Problem' + example: + type: https://example.com/errors/forbidden + title: Forbidden + status: 403 + detail: Access is forbidden with the provided credentials. + application/problem+xml: + schema: + $ref: '#/components/schemas/Problem' + example: + type: https://example.com/errors/forbidden + title: Forbidden + status: 403 + detail: Access is forbidden with the provided credentials. + InternalServerError: + description: Internal Server Error + headers: + RateLimit: + $ref: '#/components/headers/RateLimit' + content: + application/problem+json: + schema: + $ref: '#/components/schemas/Problem' + example: + type: https://example.com/errors/internal-server-error + title: Internal Server Error + status: 500 + detail: An unexpected error occurred. + application/problem+xml: + schema: + $ref: '#/components/schemas/Problem' + example: + type: https://example.com/errors/internal-server-error + title: Internal Server Error + status: 500 + detail: An unexpected error occurred. + NotFound: + description: Not Found + headers: + RateLimit: + $ref: '#/components/headers/RateLimit' + content: + application/problem+json: + schema: + $ref: '#/components/schemas/Problem' + example: + type: https://example.com/errors/not-found + title: Not Found + status: 404 + detail: The requested resource was not found. + application/problem+xml: + schema: + $ref: '#/components/schemas/Problem' + example: + type: https://example.com/errors/not-found + title: Not Found + status: 404 + detail: The requested resource was not found. + TooManyRequests: + description: Too Many Requests + headers: + RateLimit: + $ref: '#/components/headers/RateLimit' + Retry-After: + $ref: '#/components/headers/Retry-After' + content: + application/problem+json: + schema: + $ref: '#/components/schemas/Problem' + example: + type: https://example.com/errors/too-many-requests + title: Too Many Requests + status: 429 + detail: You have exceeded the rate limit. + application/problem+xml: + schema: + $ref: '#/components/schemas/Problem' + example: + type: https://example.com/errors/too-many-requests + title: Too Many Requests + status: 429 + detail: You have exceeded the rate limit. + Unauthorized: + description: Unauthorized + headers: + RateLimit: + $ref: '#/components/headers/RateLimit' + content: + application/problem+json: + schema: + $ref: '#/components/schemas/Problem' + example: + type: https://example.com/errors/unauthorized + title: Unauthorized + status: 401 + detail: You do not have the necessary permissions. + application/problem+xml: + schema: + $ref: '#/components/schemas/Problem' + example: + type: https://example.com/errors/unauthorized + title: Unauthorized + status: 401 + detail: You do not have the necessary permissions. diff --git a/.microcks/overlays.yaml b/.microcks/overlays.yaml new file mode 100644 index 0000000..07e9878 --- /dev/null +++ b/.microcks/overlays.yaml @@ -0,0 +1,204 @@ +overlay: 1.0.0 +info: + title: Train Travel API - Microcks + description: | + This API is a mock server for the Train Travel API, which provides a way to + find and book train trips across Europe. It includes endpoints for finding + stations, getting timetables, and managing bookings. + version: 1.0.0 + +actions: + + - target: $["x-topics"] + description: Remove x-topics, not needed for mock server. + remove: true + + - target: $.paths["/stations"].get.responses["200"].content["application/json"]["example"] + description: Remove the example from get /stations. + remove: true + + - target: $.paths["/stations"].get.responses["200"].content["application/json"] + description: Add Microcks examples for get /stations. + update: + examples: + stations: + summary: A list of train stations + value: + data: + - id: efdbb9d1-02c2-4bc3-afb7-6788d8782b1e + name: Berlin Hauptbahnhof + address: Invalidenstraße 10557 Berlin, Germany + country_code: DE + timezone: Europe/Berlin + - id: b2e783e1-c824-4d63-b37a-d8d698862f1d + name: Paris Gare du Nord + address: 18 Rue de Dunkerque 75010 Paris, France + country_code: FR + timezone: Europe/Paris + links: + self: https://api.example.com/stations&page=2 + next: https://api.example.com/stations?page=3 + prev: https://api.example.com/stations?page=1 + + - target: $.paths["/trips"].get.parameters[?(@.name=="origin")].example + description: Remove the example from get /trips - origin parameter. + remove: true + + - target: $.paths["/trips"].get.parameters[?(@.name=="origin")] + description: Add Microcks examples for get /trips - origin parameter + update: + examples: + trips: + value: b2e783e1-c824-4d63-b37a-d8d698862f1d + + - target: $.paths["/trips"].get.parameters[?(@.name=="destination")].example + remove: true + + - target: $.paths["/trips"].get.parameters[?(@.name=="destination")] + update: + examples: + trips: + value: '2024-02-01T09:00:00Z' + + - target: $.paths["/trips"].get.responses["200"].content["application/json"]["example"] + remove: true + + - target: $.paths["/trips"].get.responses["200"].content["application/json"] + update: + examples: + trips: + summary: A list of available train trips + value: + data: + - id: ea399ba1-6d95-433f-92d1-83f67b775594 + origin: efdbb9d1-02c2-4bc3-afb7-6788d8782b1e + destination: b2e783e1-c824-4d63-b37a-d8d698862f1d + departure_time: '2024-02-01T10:00:00Z' + arrival_time: '2024-02-01T16:00:00Z' + price: 50 + operator: Deutsche Bahn + bicycles_allowed: true + dogs_allowed: true + - id: 4d67459c-af07-40bb-bb12-178dbb88e09f + origin: b2e783e1-c824-4d63-b37a-d8d698862f1d + destination: efdbb9d1-02c2-4bc3-afb7-6788d8782b1e + departure_time: '2024-02-01T12:00:00Z' + arrival_time: '2024-02-01T18:00:00Z' + price: 50 + operator: SNCF + bicycles_allowed: true + dogs_allowed: true + links: + self: https://api.example.com/trips?origin=efdbb9d1-02c2-4bc3-afb7-6788d8782b1e&destination=b2e783e1-c824-4d63-b37a-d8d698862f1d&date=2024-02-01 + next: https://api.example.com/trips?origin=efdbb9d1-02c2-4bc3-afb7-6788d8782b1e&destination=b2e783e1-c824-4d63-b37a-d8d698862f1d&date=2024-02-01&page=2 + + - target: $.paths["/bookings"].get.responses["200"].content["application/json"]["example"] + remove: true + + - target: $.paths["/bookings"].get.responses["200"].content["application/json"] + update: + examples: + bookings: + summary: A list of bookings + value: + data: + - id: bfc5af2c-f477-43c4-8bdf-a00bdb939d65 + trip_id: efdbb9d1-02c2-4bc3-afb7-6788d8782b1e + passenger_name: John Doe + has_bicycle: true + has_dog: true + - id: 1725ff48-ab45-4bb5-9d02-88745177dedb + trip_id: b2e783e1-c824-4d63-b37a-d8d698862f1d + passenger_name: Jane Smith + has_bicycle: false + has_dog: false + links: + self: https://api.example.com/bookings + next: https://api.example.com/bookings?page=2 + + - target: $.paths["/bookings"]["post"].responses["201"].content["application/json"]["example"] + remove: true + + - target: $.paths["/bookings"]["post"].responses["201"].content["application/json"] + update: + examples: + new_booking: + summary: New Booking + value: |- + { + "id": "{{ uuid() > put(bookingId) }}", + "trip_id": "{{ request.body/trip_id }}", + "passenger_name": "{{ request.body/passenger_name }}", + "has_bicycle": {{ request.body/has_bicycle }}, + "has_dog": {{ request.body/has_dog }}, + "links": { + "self": "https://api.example.com/bookings/{{ bookingId }}" + } + } + + - target: $.paths["/bookings/{bookingId}"].parameters[?(@.name=="bookingId")].example + remove: true + + - target: $.paths["/bookings/{bookingId}"].parameters[?(@.name=="bookingId")] + update: + examples: + booking_1725ff48-ab45-4bb5-9d02-88745177dedb: + value: 1725ff48-ab45-4bb5-9d02-88745177dedb + booking_bfc5af2c-f477-43c4-8bdf-a00bdb939d65: + value: bfc5af2c-f477-43c4-8bdf-a00bdb939d65 + + - target: $.paths["/bookings/{bookingId}"].get.responses["200"].content["application/json"]["example"] + remove: true + + - target: $.paths["/bookings/{bookingId}"].get.responses["200"].content["application/json"] + update: + examples: + booking_1725ff48-ab45-4bb5-9d02-88745177dedb: + summary: John Doe + value: + id: 1725ff48-ab45-4bb5-9d02-88745177dedb + trip_id: efdbb9d1-02c2-4bc3-afb7-6788d8782b1e + passenger_name: John Doe + has_bicycle: true + has_dog: true + links: + self: https://api.example.com/bookings/1725ff48-ab45-4bb5-9d02-88745177dedb + booking_bfc5af2c-f477-43c4-8bdf-a00bdb939d65: + summary: Billy Bikeless + value: + id: bfc5af2c-f477-43c4-8bdf-a00bdb939d65 + trip_id: efdbb9d1-02c2-4bc3-afb7-6788d8782b1e + passenger_name: Billy Bikeless + has_bicycle: false + has_dog: true + links: + self: https://api.example.com/bookings/1725ff48-ab45-4bb5-9d02-88745177dedb + + + - target: $.paths["/bookings/{bookingId}/payment"].parameters[?(@.name=="bookingId")].example + remove: true + + - target: $.paths["/bookings/{bookingId}/payment"].parameters[?(@.name=="bookingId")] + update: + examples: + Card: + value: 1725ff48-ab45-4bb5-9d02-88745177dedb + Bank: + value: 1725ff48-ab45-4bb5-9d02-88745177dedb + + - target: $.webhooks["newBooking"]["post"]["requestBody"].content["application/json"]["example"] + remove: true + + - target: $.webhooks["newBooking"]["post"]["requestBody"].content["application/json"] + update: + examples: + new_booking: + summary: New Booking + value: + id: efdbb9d1-02c2-4bc3-afb7-6788d8782b1e + trip_id: efdbb9d1-02c2-4bc3-afb7-6788d8782b1e + passenger_name: John Doe + has_bicycle: true + has_dog: true + links: + self: https://api.example.com/bookings/1725ff48-ab45-4bb5-9d02-88745177dedb diff --git a/openapi.yaml b/openapi.yaml index 415d05c..7fd0932 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -25,6 +25,7 @@ servers: - url: https://api.example.com description: Production x-internal: false + - url: https://mocks.example.com/rest description: Mock Server x-internal: false @@ -109,37 +110,28 @@ paths: content: application/json: schema: - allOf: - - $ref: '#/components/schemas/Wrapper-Collection' - - properties: - data: - type: array - items: - $ref: '#/components/schemas/Station' - - properties: - links: - allOf: - - $ref: '#/components/schemas/Links-Self' - - $ref: '#/components/schemas/Links-Pagination' - examples: - stations: - summary: A list of train stations - value: - data: - - id: efdbb9d1-02c2-4bc3-afb7-6788d8782b1e - name: Berlin Hauptbahnhof - address: Invalidenstraße 10557 Berlin, Germany - country_code: DE - timezone: Europe/Berlin - - id: b2e783e1-c824-4d63-b37a-d8d698862f1d - name: Paris Gare du Nord - address: 18 Rue de Dunkerque 75010 Paris, France - country_code: FR - timezone: Europe/Paris - links: - self: https://api.example.com/stations&page=2 - next: https://api.example.com/stations?page=3 - prev: https://api.example.com/stations?page=1 + type: object + properties: + data: + type: array + items: + $ref: '#/components/schemas/Station' + example: + data: + - id: efdbb9d1-02c2-4bc3-afb7-6788d8782b1e + name: Berlin Hauptbahnhof + address: Invalidenstraße 10557 Berlin, Germany + country_code: DE + timezone: Europe/Berlin + - id: b2e783e1-c824-4d63-b37a-d8d698862f1d + name: Paris Gare du Nord + address: 18 Rue de Dunkerque 75010 Paris, France + country_code: FR + timezone: Europe/Paris + links: + self: https://api.example.com/stations&page=2 + next: https://api.example.com/stations?page=3 + prev: https://api.example.com/stations?page=1 application/xml: schema: allOf: @@ -195,9 +187,7 @@ paths: schema: type: string format: uuid - examples: - trips: - value: b2e783e1-c824-4d63-b37a-d8d698862f1d + example: b2e783e1-c824-4d63-b37a-d8d698862f1d - name: date in: query description: The date and time of the trip in ISO 8601 format in origin station's timezone. @@ -205,9 +195,7 @@ paths: schema: type: string format: date-time - examples: - trips: - value: '2024-02-01T09:00:00Z' + example: '2024-02-01T09:00:00Z' - name: bicycles in: query description: Only return trips where bicycles are known to be allowed @@ -245,32 +233,29 @@ paths: allOf: - $ref: '#/components/schemas/Links-Self' - $ref: '#/components/schemas/Links-Pagination' - examples: - trips: - summary: A list of available train trips - value: - data: - - id: ea399ba1-6d95-433f-92d1-83f67b775594 - origin: efdbb9d1-02c2-4bc3-afb7-6788d8782b1e - destination: b2e783e1-c824-4d63-b37a-d8d698862f1d - departure_time: '2024-02-01T10:00:00Z' - arrival_time: '2024-02-01T16:00:00Z' - price: 50 - operator: Deutsche Bahn - bicycles_allowed: true - dogs_allowed: true - - id: 4d67459c-af07-40bb-bb12-178dbb88e09f - origin: b2e783e1-c824-4d63-b37a-d8d698862f1d - destination: efdbb9d1-02c2-4bc3-afb7-6788d8782b1e - departure_time: '2024-02-01T12:00:00Z' - arrival_time: '2024-02-01T18:00:00Z' - price: 50 - operator: SNCF - bicycles_allowed: true - dogs_allowed: true - links: - self: https://api.example.com/trips?origin=efdbb9d1-02c2-4bc3-afb7-6788d8782b1e&destination=b2e783e1-c824-4d63-b37a-d8d698862f1d&date=2024-02-01 - next: https://api.example.com/trips?origin=efdbb9d1-02c2-4bc3-afb7-6788d8782b1e&destination=b2e783e1-c824-4d63-b37a-d8d698862f1d&date=2024-02-01&page=2 + example: + data: + - id: ea399ba1-6d95-433f-92d1-83f67b775594 + origin: efdbb9d1-02c2-4bc3-afb7-6788d8782b1e + destination: b2e783e1-c824-4d63-b37a-d8d698862f1d + departure_time: '2024-02-01T10:00:00Z' + arrival_time: '2024-02-01T16:00:00Z' + price: 50 + operator: Deutsche Bahn + bicycles_allowed: true + dogs_allowed: true + - id: 4d67459c-af07-40bb-bb12-178dbb88e09f + origin: b2e783e1-c824-4d63-b37a-d8d698862f1d + destination: efdbb9d1-02c2-4bc3-afb7-6788d8782b1e + departure_time: '2024-02-01T12:00:00Z' + arrival_time: '2024-02-01T18:00:00Z' + price: 50 + operator: SNCF + bicycles_allowed: true + dogs_allowed: true + links: + self: https://api.example.com/trips?origin=efdbb9d1-02c2-4bc3-afb7-6788d8782b1e&destination=b2e783e1-c824-4d63-b37a-d8d698862f1d&date=2024-02-01 + next: https://api.example.com/trips?origin=efdbb9d1-02c2-4bc3-afb7-6788d8782b1e&destination=b2e783e1-c824-4d63-b37a-d8d698862f1d&date=2024-02-01&page=2 application/xml: schema: allOf: @@ -331,24 +316,21 @@ paths: allOf: - $ref: '#/components/schemas/Links-Self' - $ref: '#/components/schemas/Links-Pagination' - examples: - Bookings: - summary: A list of bookings - value: - data: - - id: bfc5af2c-f477-43c4-8bdf-a00bdb939d65 - trip_id: efdbb9d1-02c2-4bc3-afb7-6788d8782b1e - passenger_name: John Doe - has_bicycle: true - has_dog: true - - id: 1725ff48-ab45-4bb5-9d02-88745177dedb - trip_id: b2e783e1-c824-4d63-b37a-d8d698862f1d - passenger_name: Jane Smith - has_bicycle: false - has_dog: false - links: - self: https://api.example.com/bookings - next: https://api.example.com/bookings?page=2 + example: + data: + - id: efdbb9d1-02c2-4bc3-afb7-6788d8782b1e + trip_id: efdbb9d1-02c2-4bc3-afb7-6788d8782b1e + passenger_name: John Doe + has_bicycle: true + has_dog: true + - id: b2e783e1-c824-4d63-b37a-d8d698862f1d + trip_id: b2e783e1-c824-4d63-b37a-d8d698862f1d + passenger_name: Jane Smith + has_bicycle: false + has_dog: false + links: + self: https://api.example.com/bookings + next: https://api.example.com/bookings?page=2 application/xml: schema: allOf: @@ -407,21 +389,14 @@ paths: links: $ref: '#/components/schemas/Links-Self' - examples: - new_booking: - summary: New Booking - value: |- - { - "id": "{{ uuid() > put(bookingId) }}", - "trip_id": "{{ request.body/trip_id }}", - "passenger_name": "{{ request.body/passenger_name }}", - "has_bicycle": {{ request.body/has_bicycle }}, - "has_dog": {{ request.body/has_dog }}, - "links": { - "self": "https://api.example.com/bookings/{{ bookingId }}" - } - } - + example: + id: efdbb9d1-02c2-4bc3-afb7-6788d8782b1e + trip_id: efdbb9d1-02c2-4bc3-afb7-6788d8782b1e + passenger_name: John Doe + has_bicycle: true + has_dog: true + links: + self: https://api.example.com/bookings/efdbb9d1-02c2-4bc3-afb7-6788d8782b1e application/xml: schema: allOf: @@ -451,11 +426,7 @@ paths: schema: type: string format: uuid - examples: - booking_1725ff48-ab45-4bb5-9d02-88745177dedb: - value: 1725ff48-ab45-4bb5-9d02-88745177dedb - booking_bfc5af2c-f477-43c4-8bdf-a00bdb939d65: - value: bfc5af2c-f477-43c4-8bdf-a00bdb939d65 + example: 1725ff48-ab45-4bb5-9d02-88745177dedb get: summary: Get a booking description: Returns the details of a specific booking. @@ -478,27 +449,14 @@ paths: - properties: links: $ref: '#/components/schemas/Links-Self' - examples: - booking_1725ff48-ab45-4bb5-9d02-88745177dedb: - summary: John Doe - value: - id: 1725ff48-ab45-4bb5-9d02-88745177dedb - trip_id: efdbb9d1-02c2-4bc3-afb7-6788d8782b1e - passenger_name: John Doe - has_bicycle: true - has_dog: true - links: - self: https://api.example.com/bookings/1725ff48-ab45-4bb5-9d02-88745177dedb - booking_bfc5af2c-f477-43c4-8bdf-a00bdb939d65: - summary: Billy Bikeless - value: - id: bfc5af2c-f477-43c4-8bdf-a00bdb939d65 - trip_id: efdbb9d1-02c2-4bc3-afb7-6788d8782b1e - passenger_name: Billy Bikeless - has_bicycle: false - has_dog: true - links: - self: https://api.example.com/bookings/1725ff48-ab45-4bb5-9d02-88745177dedb + example: + id: efdbb9d1-02c2-4bc3-afb7-6788d8782b1e + trip_id: efdbb9d1-02c2-4bc3-afb7-6788d8782b1e + passenger_name: John Doe + has_bicycle: true + has_dog: true + links: + self: https://api.example.com/bookings/1725ff48-ab45-4bb5-9d02-88745177dedb application/xml: schema: allOf: @@ -678,17 +636,14 @@ webhooks: allOf: - $ref: '#/components/schemas/Links-Self' - $ref: '#/components/schemas/Links-Pagination' - examples: - new_booking: - summary: New Booking - value: - id: efdbb9d1-02c2-4bc3-afb7-6788d8782b1e - trip_id: efdbb9d1-02c2-4bc3-afb7-6788d8782b1e - passenger_name: John Doe - has_bicycle: true - has_dog: true - links: - self: https://api.example.com/bookings/1725ff48-ab45-4bb5-9d02-88745177dedb + example: + id: efdbb9d1-02c2-4bc3-afb7-6788d8782b1e + trip_id: efdbb9d1-02c2-4bc3-afb7-6788d8782b1e + passenger_name: John Doe + has_bicycle: true + has_dog: true + links: + self: https://api.example.com/bookings/1725ff48-ab45-4bb5-9d02-88745177dedb responses: '200': description: Return a 200 status to indicate that the data was received successfully.