openapi: '3.0.1'
info:
  title: Fruit Shop API
  description: >-
    ![Logo](https://www.predic8.de/logo6.png)

    Showcases REST API design and serves as a public API for
    educational usage. Feel free to use this API even by using the POST, PUT and DELETE methods. You
    cannot do any harm, the API will be reset automatically.
  contact:
    name: Predic8
    url: https://www.predic8.de
    email: info@predic8.de
  version: 2.2.0

servers:
  - url: https://api.predic8.de/shop/v2

tags:
  - name: Products
  - name: Vendors

security:
  - jwt: []

paths:
  /products:
    get:
      tags:
        - Products
      summary: Get all products
      description: Get a list of all the products available over the Fruitshop API.
      operationId: getProducts
      responses:
        '200':
          $ref: '#/components/responses/Products'

    post:
      tags:
        - Products
      summary: Create a product
      description: Create a new product for the store.
      operationId: createProduct
      security:
        - jwt: [inventory]
      requestBody:
        $ref: '#/components/requestBodies/Product'
      responses:
        '201':
          $ref: '#/components/responses/ProductCreated'
        '5XX':
          $ref: '#/components/responses/ServerError'

  /vendors:
    get:
      tags:
        - Vendors
      summary: Get all vendors
      description: Get a list of all the vendors registered the Fruitshop API.
      operationId: getVendors
      responses:
        '200':
          $ref: '#/components/responses/Vendors'

    post:
      tags:
        - Vendors
      summary: Create a vendor
      description: Register a new vendor offering products with the **Fruitshop API**.
      operationId: createVendor
      security:
        - jwt: [management]
      requestBody:
        $ref: '#/components/requestBodies/Vendor'
      responses:
        '201':
          $ref: '#/components/responses/VendorCreated'
        '5XX':
          $ref: '#/components/responses/ServerError'

components:
  securitySchemes:
    jwt:
      type: oauth2

  requestBodies:
    Product:
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Product'
          example:
            name: Mangos
            price: 2.79
    Vendor:
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Vendor'

  responses:
    ServerError:
      description: Server Error
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ProblemDetails'

    VendorCreated:
      description: Created
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Vendor'

    Vendors:
      description: OK
      content:
        application/json:
          schema:
            type: object
            properties:
              meta:
                $ref: '#/components/schemas/Meta'
              vendors:
                type: array
                items:
                  type: object
                  properties:
                    id:
                      $ref: '#/components/schemas/Id'
                    name:
                      type: string
                      description: Name of the vendor
                      example: Exotic Fruits LLC
                    self_link:
                      $ref: '#/components/schemas/SelfLink'

    ProductCreated:
      description: Created
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Product'

    Products:
      description: OK
      content:
        application/json:
          schema:
            type: object
            properties:
              meta:
                $ref: '#/components/schemas/Meta'
              products:
                type: array
                items:
                  type: object
                  properties:
                    id:
                      $ref: '#/components/schemas/Id'
                    name:
                      type: string
                      description: Name of the product
                      example: Cherries
                    self_link:
                      $ref: '#/components/schemas/SelfLink'

  schemas:
    Id:
      type: integer
      description: Id of an object
      example: 8
      minimum: 1
      readOnly: true

    SelfLink:
      type: string
      format: url
      description: Link to the resource itself
      example: /shop/v2/...
      readOnly: true

    Meta:
      type: object
      description: Metadata about a collection of resources.
      properties:
        count:
          type: integer
          description: Number of resources
          example: 22
        start:
          type: integer
          description: Starting entry of the result list
          example: 11
        limit:
          type: integer
          description: How many entries are delivered in one response
          example: 10
        previous_link:
          type: string
          description: URL to the previous page of results
          example: /shop/v2/products/?start=1&limit=10
        next_link:
          type: string
          description: URL to the next page of results
          example: /shop/v2/products/?start=21&limit=10
      required:
        - count

    Product:
      type: object
      description: Description of a product
      properties:
        id:
          $ref: '#/components/schemas/Id'
        name:
          type: string
          description: Name of a product
          example: Berries
          maxLength: 30
        price:
          type: number
          description: Price of a good
          example: 4.5
          maximum: 1000
          minimum: 0
        vendors:
          type: array
          items:
            type: object
            properties:
              id:
                $ref: '#/components/schemas/Id'
              name:
                type: string
                description: Name of the vendor
                example: Exotic Fruits LLC
                maxLength: 30
              self_link:
                $ref: '#/components/schemas/SelfLink'
          readOnly: true
        image_link:
          type: string
          readOnly: true
        self_link:
          $ref: '#/components/schemas/SelfLink'
        modified_at:
          type: string
          format: date-time
          description: Last time the product was modified.
      required:
        - name
        - price
      example:
        name: Wildberries
        price: 4.99

    Vendor:
      type: object
      description: Vendor of products
      properties:
        id:
          $ref: '#/components/schemas/Id'
        name:
          type: string
          description: Name of the vendor
          example: foo
          maxLength: 30
        products_link:
          type: string
          description: URL to the products of this vendor
          readOnly: true
        self_link:
          type: string
          description: URL of the vendor
      required:
        - name
      example:
        name: Fresh Fruits from France Ltd.

    ProblemDetails:
      type: object
      properties:
        type:
          type: string
          format: url
        title:
          type: string
        status:
          type: integer
          minimum: 200
        detail:
          type: string
          maxLength: 500