openapi: 3.0.3 info: title: KITCC Library API contact: name: KITCC url: https://www.kitcc.org/ email: question@kitcc.org license: name: MIT url: https://en.wikipedia.org/wiki/MIT_License version: 1.0.0 servers: - url: https://kitcc-library-api.kitcc.workers.dev tags: - name: book description: 書籍に関するAPI - name: user description: ユーザーに関するAPI - name: loan description: 貸出履歴に関するAPI - name: auth description: 認証に関するAPI - name: google-books description: Google Books から書籍の情報を取得するAPI paths: /books: get: tags: - book operationId: getBooks summary: 書籍の情報を取得する description: ページ番号が指定されなかった場合は1ページ目を返す security: [] parameters: - name: page in: query description: ページ番号 required: false schema: type: string pattern: ^[1-9]\d*$ minimum: 1 default: 1 - name: limit in: query description: 1ページあたりの表示数 required: false schema: type: string pattern: ^[1-9]\d*$ minimum: 1 default: 10 - name: title in: query description: タイトル required: false schema: type: string - name: author in: query description: 著者 required: false schema: type: string - name: publisher in: query description: 出版社 required: false schema: type: string - name: isbn in: query description: ISBN required: false schema: type: string pattern: ^\d{10}(\d{3})?$ - name: sort in: query description: | ソート順 0: id昇順 1: id降順 2: 出版日昇順 3: 出版日降順 required: false schema: type: string enum: - '0' - '1' - '2' - '3' default: '0' responses: '200': description: 情報の取得に成功した content: application/json: schema: type: object properties: totalBook: description: 総書籍数 type: integer books: type: array items: $ref: '#/components/schemas/Book' required: - totalBook - books '400': $ref: '#/components/responses/BadRequest' '500': $ref: '#/components/responses/InternalServerError' post: tags: - book operationId: createBook summary: 書籍を追加する security: - CookieAuth: [] requestBody: required: true content: application/json: schema: type: object properties: title: type: string authors: type: array items: type: string publisher: type: string publishedDate: type: string description: type: string thumbnail: type: string isbn: type: string pattern: ^\d{10}(\d{3})?$ stock: type: integer required: - title - authors - publisher - publishedDate - description - isbn - stock example: title: 計算機プログラムの構造と解釈 author: - Harold Abelson - Gerald Jay Sussman - Julie Sussman publisher: 翔泳社 publishedDate: '2018-07-01' description: 言わずと知れた計算機科学の古典的名著 thumbnail: http://books.google.com/books/content?id=LlH-oAEACAAJ&printsec=frontcover&img=1&zoom=1&source=gbs_api isbn: '9784798135984' stock: 1 responses: '201': description: 書籍の追加に成功した content: application/json: schema: $ref: '#/components/schemas/Book' examples: book: $ref: '#/components/examples/book' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '500': $ref: '#/components/responses/InternalServerError' delete: tags: - book operationId: deleteBooks summary: 指定された1冊以上の書籍を削除する security: - CookieAuth: [] requestBody: required: true content: application/json: schema: type: object properties: bookIdList: type: array items: type: integer required: - bookIdList example: bookIdList: - 1 - 2 - 3 responses: '204': description: 書籍の削除に成功した '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '500': $ref: '#/components/responses/InternalServerError' /books/{bookId}: get: tags: - book operationId: getBook summary: 特定の書籍の情報を取得する security: [] parameters: - name: bookId in: path description: 取得する書籍のID required: true schema: type: string pattern: ^\d+$ responses: '200': description: 情報の取得に成功した content: application/json: schema: $ref: '#/components/schemas/Book' examples: book: $ref: '#/components/examples/book' '400': $ref: '#/components/responses/BadRequest' '404': $ref: '#/components/responses/NotFound' '500': $ref: '#/components/responses/InternalServerError' patch: tags: - book operationId: updateBook summary: 特定の書籍の情報を更新する description: | リクエストボディで指定された情報のみ更新する. 書籍が登録済みの場合は蔵書数を+1する. security: - CookieAuth: [] parameters: - name: bookId in: path description: 更新する書籍のID required: true schema: type: string pattern: ^\d+$ requestBody: required: true content: application/json: schema: type: object properties: title: type: string authors: type: array items: type: string publisher: type: string publishedDate: type: string format: date isbn: type: string pattern: ^\d{10}(\d{3})?$ stock: type: integer example: title: 計算機プログラムの構造と解釈 authors: - Harold Abelson - Gerald Jay Sussman - Julie Sussman publisher: 翔泳社 publishedDate: '2018-07-01' isbn: '9784798135984' stock: 1 responses: '200': description: 情報の更新に成功した content: application/json: schema: $ref: '#/components/schemas/Book' examples: book: $ref: '#/components/examples/book' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' '500': $ref: '#/components/responses/InternalServerError' delete: tags: - book operationId: deleteBook summary: 特定の書籍を削除する security: - CookieAuth: [] parameters: - name: bookId in: path description: 削除する書籍のID required: true schema: type: string pattern: ^\d+$ responses: '204': description: 書籍の削除に成功した '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' '500': $ref: '#/components/responses/InternalServerError' /googlebooks: get: tags: - google-books operationId: searchGoogleBooks summary: Google Books から書籍を検索する security: [] parameters: - name: page in: query description: ページ番号 required: false schema: type: string pattern: ^[1-9]\d*$ minimum: 1 default: 1 - name: limit in: query description: 1ページあたりの表示数 required: false schema: type: string pattern: ^[1-9]\d*$ minimum: 1 maximum: 40 default: 10 - name: keyword in: query description: 検索キーワード required: false schema: type: string - name: intitle in: query description: タイトル required: false schema: type: string - name: inauthor in: query description: 著者 required: false schema: type: string - name: inpublisher in: query description: 出版社 required: false schema: type: string - name: isbn in: query description: ISBN required: false schema: type: string pattern: ^\d{10}(\d{3})?$ responses: '200': description: 検索に成功した content: application/json: schema: type: object properties: totalBook: description: 総書籍数 type: integer books: type: array items: $ref: '#/components/schemas/GoogleBook' required: - totalBook - books '400': $ref: '#/components/responses/BadRequest' '500': $ref: '#/components/responses/InternalServerError' /googlebooks/{volumeId}: get: tags: - google-books operationId: getGoogleBook summary: Google Books から特定の書籍の情報を取得する security: [] parameters: - name: volumeId in: path description: Google BooksのID required: true schema: type: string responses: '200': description: 情報の取得に成功した content: application/json: schema: $ref: '#/components/schemas/GoogleBook' examples: book: $ref: '#/components/examples/google-book' '400': $ref: '#/components/responses/BadRequest' '404': $ref: '#/components/responses/NotFound' '500': $ref: '#/components/responses/InternalServerError' /users: get: tags: - user operationId: getUsers summary: ユーザーの情報を取得する description: ページ番号が指定されなかった場合は1ページ目を返す security: [] parameters: - name: page in: query description: ページ番号 required: false schema: type: string pattern: ^[1-9]\d*$ minimum: 1 default: 1 - name: limit in: query description: 1ページあたりの表示数 required: false schema: type: string pattern: ^[1-9]\d*$ minimum: 1 default: 10 - name: name in: query description: ユーザー名 required: false schema: type: string - name: email in: query description: メールアドレス required: false schema: type: string format: email responses: '200': description: 情報の取得に成功した content: application/json: schema: type: object properties: totalUser: description: 総ユーザー数 type: integer users: type: array items: type: object properties: id: type: integer name: type: string required: - totalUser - users '400': $ref: '#/components/responses/BadRequest' '500': $ref: '#/components/responses/InternalServerError' post: tags: - user operationId: createUser summary: ユーザーを追加する security: - CookieAuth: [] requestBody: required: true content: application/json: schema: type: object properties: name: type: string email: type: string format: email password: type: string format: password pattern: ^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]+$ minLength: 8 required: - name - email - password example: name: 比企谷八幡 email: hikigaya@oregairu.com password: passw0rd responses: '201': description: ユーザーの追加に成功した content: application/json: schema: $ref: '#/components/schemas/User' examples: user: $ref: '#/components/examples/user' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '409': description: すでに同じメールアドレスで登録されたユーザーが存在する content: application/json: schema: $ref: '#/components/schemas/Error' example: message: Conflict '500': $ref: '#/components/responses/InternalServerError' delete: tags: - user operationId: deleteUsers summary: 指定された1人以上のユーザーを削除する security: - CookieAuth: [] requestBody: required: true content: application/json: schema: type: object properties: userIdList: type: array items: type: integer required: - userIdList example: userIdList: - 1 - 2 - 3 responses: '204': description: ユーザーの削除に成功した '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '500': $ref: '#/components/responses/InternalServerError' /users/{userId}: get: tags: - user operationId: getUser summary: 特定のユーザーの情報を取得する security: - CookieAuth: [] parameters: - name: userId in: path description: 取得するユーザーのID required: true schema: type: string pattern: ^\d+$ responses: '200': description: 情報の取得に成功した content: application/json: schema: $ref: '#/components/schemas/User' examples: user: $ref: '#/components/examples/user' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' '500': $ref: '#/components/responses/InternalServerError' patch: tags: - user operationId: updateUser summary: 特定のユーザーの情報を更新する description: リクエストボディに含まれている情報のみ更新する security: - CookieAuth: [] parameters: - name: userId in: path description: 更新するユーザーのID required: true schema: type: string pattern: ^\d+$ requestBody: required: true content: application/json: schema: type: object properties: name: type: string email: type: string format: email currentPassword: type: string format: password pattern: ^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]+$ minLength: 8 newPassword: type: string format: password pattern: ^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]+$ minLength: 8 example: name: 比企谷八幡 email: hikigaya@oregairu.com currentPassword: passw0rd newPassword: pa55word responses: '200': description: 情報の更新に成功した content: application/json: schema: $ref: '#/components/schemas/User' examples: user: $ref: '#/components/examples/user' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' '500': $ref: '#/components/responses/InternalServerError' delete: tags: - user operationId: deleteUser summary: 特定のユーザーを削除する security: - CookieAuth: [] parameters: - name: userId in: path description: 削除するユーザーのID required: true schema: type: string pattern: ^\d+$ responses: '204': description: ユーザーの削除に成功した content: application/json: schema: type: object properties: message: type: string example: message: No Content '400': $ref: '#/components/responses/BadRequest' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/Error' '404': $ref: '#/components/responses/NotFound' '500': $ref: '#/components/responses/InternalServerError' /loans: get: tags: - loan operationId: getLoans summary: 貸出履歴を取得する description: 指定された条件に合致する貸出履歴を返す security: - CookieAuth: [] parameters: - name: userId in: query description: 貸出履歴を取得するユーザーのID required: false schema: type: string pattern: ^\d+$ - name: bookId in: query description: 貸出履歴を取得する書籍のID required: false schema: type: string pattern: ^\d+$ - name: page in: query description: ページ番号 required: false schema: type: string pattern: ^[1-9]\d*$ minimum: 1 default: 1 - name: limit in: query description: 1ページあたりの表示数 required: false schema: type: string pattern: ^[1-9]\d*$ minimum: 1 default: 10 - name: sort in: query description: | ソート順 0: ユーザID昇順 1: ユーザID降順 2: 書籍ID昇順 3: 書籍ID降順 4: 貸出日昇順 5: 貸出日降順 required: false schema: type: string enum: - '0' - '1' - '2' - '3' - '4' - '5' default: '2' responses: '200': description: OK content: application/json: schema: type: object properties: totalLoan: type: integer loans: type: array items: type: object properties: loans: $ref: '#/components/schemas/Loan' users: $ref: '#/components/schemas/User' books: $ref: '#/components/schemas/Book' required: - totalLoan - loans '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '500': $ref: '#/components/responses/InternalServerError' patch: tags: - loan operationId: upsertLoans summary: 貸出履歴を更新する security: - CookieAuth: [] requestBody: required: true content: application/json: schema: type: array items: type: object properties: userId: type: integer bookId: type: integer volume: type: integer required: - userId - bookId - volume responses: '200': description: OK content: application/json: schema: type: array items: $ref: '#/components/schemas/Loan' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '404': description: ユーザーまたは書籍が存在しない content: application/json: schema: type: object properties: userId: type: integer bookId: type: integer required: - userId - bookId '409': description: | 貸出数が在庫数を超えている. 返却数が貸出数を超えている. content: application/json: schema: description: 貸出数が在庫数を超えているリクエスト type: object properties: userId: type: integer bookId: type: integer volume: type: integer required: - userId - bookId - volume '500': $ref: '#/components/responses/InternalServerError' /auth: post: tags: - auth operationId: login summary: ログインする description: セッションIDをCookieに保存する security: [] requestBody: required: true content: application/json: schema: type: object properties: email: type: string format: email password: type: string format: password pattern: ^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]+$ minLength: 8 required: - email - password example: email: username@example.com password: passw0rd responses: '200': description: | ログインに成功した. `session_token`という名前のCookieにセッションIDが保存される. 以降のリクエストにはこのCookieを含める必要がある. headers: Set-Cookie: schema: type: string example: session_token=abcde12345; Path=/; HttpOnly content: application/json: schema: $ref: '#/components/schemas/User' examples: user: $ref: '#/components/examples/user' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' '500': $ref: '#/components/responses/InternalServerError' delete: tags: - auth operationId: logout summary: ログアウトする description: CookieからセッションIDを削除する security: [] responses: '204': description: ログアウトに成功した headers: Set-Cookie: schema: type: string example: session_token=; Path=/; Max-Age=0 '500': $ref: '#/components/responses/InternalServerError' components: securitySchemes: CookieAuth: type: apiKey in: cookie name: __Secure-session_token schemas: Book: type: object properties: id: type: integer title: type: string authors: type: array items: type: string publisher: type: string publishedDate: type: string description: type: string thumbnail: type: string format: uri isbn: type: string pattern: ^\d{10}(\d{3})?$ stock: type: integer required: - id - title - authors - publisher - publishedDate - description - isbn - stock Error: type: object properties: message: type: string required: - message GoogleBook: type: object properties: id: type: string title: type: string authors: type: array items: type: string publisher: type: string publishedDate: type: string description: type: string thumbnail: type: string isbn: type: string required: - id - title - authors User: type: object properties: id: type: integer name: type: string email: type: string format: email sessionToken: type: string nullable: true required: - id - name - email Loan: type: object properties: userId: type: integer bookId: type: integer volume: type: integer createdAt: type: integer description: レコードが作成されたUNIX時間 updatedAt: type: integer description: レコードが最後に更新されたUNIX時間 required: - userId - bookId - volume responses: BadRequest: description: リクエストの構文が誤っている content: application/json: schema: $ref: '#/components/schemas/Error' example: message: Bad Request InternalServerError: description: サーバ内部でエラーが発生した content: application/json: schema: $ref: '#/components/schemas/Error' example: message: Internal Server Error Unauthorized: description: 適切な認証情報を持たずにリソースにアクセスしようとした content: application/json: schema: $ref: '#/components/schemas/Error' example: message: Unauthorized NotFound: description: 指定されたリソースが存在しない content: application/json: schema: $ref: '#/components/schemas/Error' example: message: Not Found examples: book: value: id: 1 title: 計算機プログラムの構造と解釈 authors: - Harold Abelson - Gerald Jay Sussman - Julie Sussman publisher: 翔泳社 publishedDate: '2012-07-06' description: 言わずと知れた計算機科学の古典的名著 thumbnail: http://books.google.com/books/content?id=LlH-oAEACAAJ&printsec=frontcover&img=1&zoom=1&source=gbs_api isbn: '9784798135984' stock: 1 google-book: value: id: 5-OgzgEACAAJ title: 計算機プログラムの構造と解釈 authors: - Harold Abelson - Gerald Jay Sussman - Julie Sussman publisher: 翔泳社 publishedDate: '2018-07-01' description: 言わずと知れた計算機科学の古典的名著 thumbnail: http://books.google.com/books/content?id=LlH-oAEACAAJ&printsec=frontcover&img=1&zoom=1&source=gbs_api isbn: '9784798135984' user: value: id: 1 name: 比企谷八幡 email: hikigaya@oregairu.com sessionToken: abcde12345