openapi: 3.0.0
info:
  description: This is a test api description where operations have multiple tags
  version: 1.0.0
  title: Library
  license:
    name: Apache-2.0
    url: 'https://www.apache.org/licenses/LICENSE-2.0.html'
tags:
  - {name: books, description: Everything about books}
  - {name: authors, description: Everything about book authors}
  - {name: search, description: Tags for useful searching}
paths:
  /book/{bookName}:
    get:
      tags: [books]
      summary: Get a book by name
      operationId: getBook
      parameters:
        - {name: bookName, in: path, required: true, schema: {type: string}}
      responses:
        '200':
          description: success
          content:
            application/json:
              schema: { $ref: "#/components/schemas/Book" }
  /book/availability/{bookName}:
    get:
      tags: [books]
      summary: Check book availability
      operationId: isBookAvailable
      parameters:
        - { name: bookName, in: path, required: true, schema: { type: string, example: "Book 1" } }
      responses:
        '200':
          description: success
          content:
            text/plain:
              schema: { $ref: "#/components/schemas/BookAvailability" }
  /book/search:
    get:
      tags: [books, search]
      summary: Search for a book
      parameters:
        - {name: bookName, in: query, required: false, schema: {type: string, example: "Book 2"}}
        - {name: ISBN, in: query, required: false, schema: {type: string, pattern: "[0-9]{13}", example: "0123456789123"}}
        - {name: published, in: query, required: false, schema: {type: string, format: date}}
        - {name: minNumPages, in: query, required: false, schema: {type: integer, format: int32, minimum: 1, maximum: 1000}}
        - {name: minReadTime, in: query, required: false, schema: {type: number, format: float, minimum: 1, example: 5.7}}
        - {name: description, in: query, required: false, schema: {type: string, minLength: 4, nullable: true}}
        - {name: preferences, in: cookie, required: false, schema: {type: string}}
        - {name: geoLocation, in: header, required: false, schema: {type: string}}
      responses:
        '200':
          description: success
          content:
            application/json:
              schema: { type: array, items: { $ref: "#/components/schemas/Book" } }
  /book/sendReview:
    post:
      tags: [books]
      summary: Send a review to a book
      parameters:
        - {name: bookName, in: query, required: true, schema: {type: string, nullable: false}}
      requestBody:
        content:
          application/x-www-form-urlencoded:
            schema: {$ref: "#/components/schemas/Review"}
      responses:
        '200':
          description: success
  /book/createEntry:
    post:
      tags: [books]
      summary: Create a new entry for a book
      requestBody:
        content:
          application/json: { schema: { $ref: "#/components/schemas/Book" } }
          application/xml: { schema: { $ref: "#/components/schemas/Book" } }
      responses:
        '200':
          description: success
          content:
            application/json: { schema: { $ref: "#/components/schemas/Book" } }
            application/xml: { schema: { $ref: "#/components/schemas/Book" } }
  /author/{authorName}:
    get:
      tags: [authors]
      summary: Get an author by name
      operationId: getAuthor
      parameters:
        - {name: authorName, in: path, required: true, schema: {type: string}}
      responses:
        '200':
          description: success
          content:
            application/json:
              schema: { $ref: "#/components/schemas/Author" }
  /author/search:
    get:
      tags: [authors, search]
      summary: Search for an author
      parameters:
        - {name: authorName, in: query, required: false, schema: {type: string, example: "Eric Berne"}}
        - {name: approximateYearBorn, in: query, required: false, schema: {type: int, example: 1990}}
      responses:
        '200':
          description: success
          content:
            application/json:
              schema: { type: array, items: { $ref: "#/components/schemas/Author" } }
  /author/{authorName}/getBooks:
    get:
      tags: [authors, books]
      summary: Get books by author name
      operationId: getAuthorBooks
      parameters:
        - {name: authorName, in: path, required: true, schema: {type: string}}
      responses:
        '200':
          description: success
          content:
            application/json:
              schema: { type: array, items: { $ref: "#/components/schemas/Book" } }
components:
  schemas:
    Book:
      title: Book
      description: book instance
      type: object
      properties:
        name: {type: string}
        availability: {$ref: "#/components/schemas/BookAvailability"}
        pages: {type: integer, format: int32, minimum: 1}
        readTime: {type: number, format: float, minimum: 0, exclusiveMinimum: true}
        author: {$ref: "#/components/schemas/Author"}
      required: ["name", "availability"]
      default:
        name: "Bob's Adventures"
        availability: "available"
    BookAvailability: 
      type: string
      enum: ["available", "not available", "reserved"]
      default: "not available"
    Review:
      type: object
      properties:
        rating: {type: integer, minimum: 1, maximum: 5, default: 2}
        description: {type: string, maxLength: 200}
      required: [rating]
    Author:
      type: object
      properties:
        name: {type: string, pattern: "[a-zA-z ]+"}
        yearBorn: {type: int, minimum: 0, maximum: 2030}
