CMU Coding Bootcamp
1{
2 "openapi": "3.0.2",
3 "info": {
4 "title": "Library Book Management API",
5 "version": "1.0.0",
6 "description": "A RESTful API for managing books in a library"
7 },
8 "servers": [
9 {
10 "url": "http://localhost:3000",
11 "description": "Local development server"
12 }
13 ],
14 "components": {
15 "schemas": {
16 "Book": {
17 "type": "object",
18 "required": ["isbn", "title", "authors"],
19 "properties": {
20 "isbn": {
21 "type": "string",
22 "pattern": "^(?:ISBN(?:-13)?:? )?(?=[0-9]{13}$|(?=(?:[0-9]+[- ]){4})[- 0-9]{17}$)[\\d-]+$",
23 "description": "ISBN-13 identifier for the book",
24 "example": "978-3-16-148410-0"
25 },
26 "title": {
27 "type": "string",
28 "description": "Title of the book",
29 "example": "Example Book Title"
30 },
31 "authors": {
32 "type": "array",
33 "items": {
34 "type": "string"
35 },
36 "description": "List of authors",
37 "example": ["John Doe", "Jane Smith"]
38 },
39 "publicationYear": {
40 "type": "integer",
41 "description": "Year of publication",
42 "example": 2023
43 },
44 "genres": {
45 "type": "array",
46 "items": {
47 "type": "string"
48 },
49 "description": "Genres or categories",
50 "example": ["Fiction", "Science Fiction"]
51 },
52 "pageCount": {
53 "type": "integer",
54 "description": "Total number of pages",
55 "example": 350
56 },
57 "averageRating": {
58 "type": "number",
59 "format": "float",
60 "minimum": 0,
61 "maximum": 10,
62 "description": "Average rating from 0 to 10",
63 "example": 4.5
64 },
65 "numberOfRatings": {
66 "type": "integer",
67 "description": "Total number of ratings",
68 "example": 1250
69 }
70 }
71 },
72 "PartialBook": {
73 "type": "object",
74 "properties": {
75 "isbn": {
76 "type": "string",
77 "pattern": "^(?:ISBN(?:-13)?:? )?(?=[0-9]{13}$|(?=(?:[0-9]+[- ]){4})[- 0-9]{17}$)[\\d-]+$",
78 "description": "ISBN-13 identifier for the book"
79 },
80 "title": {
81 "type": "string",
82 "description": "Title of the book"
83 },
84 "authors": {
85 "type": "array",
86 "items": {
87 "type": "string"
88 },
89 "description": "List of authors"
90 },
91 "publicationYear": {
92 "type": "integer",
93 "description": "Year of publication"
94 },
95 "genres": {
96 "type": "array",
97 "items": {
98 "type": "string"
99 },
100 "description": "Genres or categories"
101 },
102 "pageCount": {
103 "type": "integer",
104 "description": "Total number of pages"
105 },
106 "averageRating": {
107 "type": "number",
108 "format": "float",
109 "minimum": 0,
110 "maximum": 10,
111 "description": "Average rating from 0 to 10"
112 },
113 "numberOfRatings": {
114 "type": "integer",
115 "description": "Total number of ratings"
116 }
117 }
118 },
119 "BadDataIssues": {
120 "type": "object",
121 "properties": {
122 "missingKeys": {
123 "type": "array",
124 "items": {
125 "type": "string"
126 },
127 "description": "Required fields that are missing"
128 },
129 "extraKeys": {
130 "type": "array",
131 "items": {
132 "type": "string"
133 },
134 "description": "Fields that are not allowed"
135 },
136 "badValues": {
137 "type": "array",
138 "items": {
139 "type": "array",
140 "items": {
141 "type": "string"
142 },
143 "minItems": 2,
144 "maxItems": 2
145 },
146 "description": "Fields with invalid values and their expected types"
147 }
148 }
149 },
150 "AuthRequest": {
151 "type": "object",
152 "required": ["username", "password"],
153 "properties": {
154 "username": {
155 "type": "string",
156 "description": "User email or username",
157 "example": "user@example.com"
158 },
159 "password": {
160 "type": "string",
161 "description": "User password",
162 "example": "password123"
163 }
164 }
165 },
166 "APIKeyResponse": {
167 "type": "object",
168 "properties": {
169 "key": {
170 "type": "string",
171 "description": "API key for authentication",
172 "example": "abc123def456ghi789"
173 }
174 }
175 },
176 "BookErrorResponse": {
177 "type": "object",
178 "properties": {
179 "error": {
180 "type": "string",
181 "description": "Error message with error type prefix",
182 "example": "BookError: Book 9783161484100 not found"
183 },
184 "missingKeys": {
185 "type": "array",
186 "items": {
187 "type": "string"
188 },
189 "description": "Required fields that are missing (only for BadData errors)"
190 },
191 "extraKeys": {
192 "type": "array",
193 "items": {
194 "type": "string"
195 },
196 "description": "Fields that are not allowed (only for BadData errors)"
197 },
198 "badValues": {
199 "type": "array",
200 "items": {
201 "type": "array",
202 "items": {
203 "type": "string"
204 },
205 "minItems": 2,
206 "maxItems": 2
207 },
208 "description": "Fields with invalid values (only for BadData errors)"
209 }
210 }
211 },
212 "InternalServerError": {
213 "type": "object",
214 "properties": {
215 "error": {
216 "type": "string",
217 "example": "Internal Server Error"
218 }
219 }
220 }
221 },
222 "securitySchemes": {
223 "ApiKeyAuth": {
224 "type": "apiKey",
225 "in": "header",
226 "name": "x-api-key",
227 "description": "API key obtained from the /auth endpoint"
228 }
229 },
230 "parameters": {
231 "ISBNPathParam": {
232 "name": "isbn",
233 "in": "path",
234 "required": true,
235 "schema": {
236 "type": "string",
237 "pattern": "^(?:ISBN(?:-13)?:? )?(?=[0-9]{13}$|(?=(?:[0-9]+[- ]){4})[- 0-9]{17}$)[\\d-]+$"
238 },
239 "description": "ISBN-13 identifier for the book"
240 }
241 }
242 },
243 "paths": {
244 "/auth": {
245 "post": {
246 "summary": "Authenticate user and obtain API key",
247 "operationId": "authenticateUser",
248 "requestBody": {
249 "required": true,
250 "content": {
251 "application/json": {
252 "schema": {
253 "$ref": "#/components/schemas/AuthRequest"
254 }
255 }
256 }
257 },
258 "responses": {
259 "200": {
260 "description": "Authentication successful",
261 "content": {
262 "application/json": {
263 "schema": {
264 "$ref": "#/components/schemas/APIKeyResponse"
265 }
266 }
267 }
268 },
269 "401": {
270 "description": "Invalid credentials",
271 "content": {
272 "application/json": {
273 "schema": {
274 "type": "object",
275 "properties": {
276 "error": {
277 "type": "string",
278 "example": "BookError: Invalid username or password"
279 }
280 }
281 }
282 }
283 }
284 },
285 "500": {
286 "description": "Internal server error",
287 "content": {
288 "application/json": {
289 "schema": {
290 "$ref": "#/components/schemas/InternalServerError"
291 }
292 }
293 }
294 }
295 }
296 }
297 },
298 "/": {
299 "get": {
300 "summary": "Get all books",
301 "operationId": "getAllBooks",
302 "responses": {
303 "200": {
304 "description": "List of all books",
305 "content": {
306 "application/json": {
307 "schema": {
308 "type": "array",
309 "items": {
310 "$ref": "#/components/schemas/Book"
311 }
312 }
313 }
314 }
315 },
316 "500": {
317 "description": "Internal server error",
318 "content": {
319 "application/json": {
320 "schema": {
321 "$ref": "#/components/schemas/InternalServerError"
322 }
323 }
324 }
325 }
326 }
327 },
328 "post": {
329 "summary": "Create a new book",
330 "operationId": "createBook",
331 "security": [
332 {
333 "ApiKeyAuth": []
334 }
335 ],
336 "requestBody": {
337 "required": true,
338 "content": {
339 "application/json": {
340 "schema": {
341 "$ref": "#/components/schemas/Book"
342 }
343 }
344 }
345 },
346 "responses": {
347 "201": {
348 "description": "Book created successfully",
349 "content": {
350 "application/json": {
351 "schema": {
352 "$ref": "#/components/schemas/Book"
353 }
354 }
355 }
356 },
357 "400": {
358 "description": "Invalid book data or missing required fields",
359 "content": {
360 "application/json": {
361 "schema": {
362 "$ref": "#/components/schemas/BookErrorResponse"
363 }
364 }
365 }
366 },
367 "401": {
368 "description": "Unauthorized - invalid or missing API key",
369 "content": {
370 "application/json": {
371 "schema": {
372 "type": "object",
373 "properties": {
374 "error": {
375 "type": "string",
376 "example": "Unauthorized"
377 }
378 }
379 }
380 }
381 }
382 },
383 "409": {
384 "description": "Book with the provided ISBN already exists",
385 "content": {
386 "application/json": {
387 "schema": {
388 "type": "object",
389 "properties": {
390 "error": {
391 "type": "string",
392 "example": "BookError: Book with id 9783161484100 already exists"
393 }
394 }
395 }
396 }
397 }
398 },
399 "500": {
400 "description": "Internal server error",
401 "content": {
402 "application/json": {
403 "schema": {
404 "$ref": "#/components/schemas/InternalServerError"
405 }
406 }
407 }
408 }
409 }
410 }
411 },
412 "/find": {
413 "get": {
414 "summary": "Filter books by query parameters",
415 "operationId": "filterBooks",
416 "parameters": [
417 {
418 "name": "publishedBefore",
419 "in": "query",
420 "schema": {
421 "type": "integer",
422 "description": "Filter books published before this year (inclusive)"
423 }
424 },
425 {
426 "name": "publishedAfter",
427 "in": "query",
428 "schema": {
429 "type": "integer",
430 "description": "Filter books published after this year (inclusive)"
431 }
432 },
433 {
434 "name": "publicationYear",
435 "in": "query",
436 "schema": {
437 "type": "integer",
438 "description": "Filter books published in this specific year"
439 }
440 },
441 {
442 "name": "title",
443 "in": "query",
444 "schema": {
445 "type": "string",
446 "description": "Search for books with titles matching this regex (case-insensitive)"
447 }
448 },
449 {
450 "name": "authors",
451 "in": "query",
452 "schema": {
453 "type": "array",
454 "items": {
455 "type": "string"
456 },
457 "description": "Filter books where at least one author matches (case-insensitive)"
458 },
459 "style": "form",
460 "explode": true
461 },
462 {
463 "name": "genres",
464 "in": "query",
465 "schema": {
466 "type": "array",
467 "items": {
468 "type": "string"
469 },
470 "description": "Filter books where at least one genre matches (case-insensitive)"
471 },
472 "style": "form",
473 "explode": true
474 },
475 {
476 "name": "isbn",
477 "in": "query",
478 "schema": {
479 "type": "string",
480 "pattern": "^(?:ISBN(?:-13)?:? )?(?=[0-9]{13}$|(?=(?:[0-9]+[- ]){4})[- 0-9]{17}$)[\\d-]+$",
481 "description": "Search for books with ISBNs matching this pattern (case-insensitive)"
482 }
483 },
484 {
485 "name": "pageCount",
486 "in": "query",
487 "schema": {
488 "type": "integer",
489 "description": "Filter books with page count greater than or equal to this value"
490 }
491 },
492 {
493 "name": "averageRating",
494 "in": "query",
495 "schema": {
496 "type": "number",
497 "format": "float",
498 "description": "Filter books with average rating greater than or equal to this value (0-10)"
499 }
500 },
501 {
502 "name": "numberOfRatings",
503 "in": "query",
504 "schema": {
505 "type": "integer",
506 "description": "Filter books with number of ratings greater than or equal to this value"
507 }
508 }
509 ],
510 "responses": {
511 "200": {
512 "description": "Filtered list of books",
513 "content": {
514 "application/json": {
515 "schema": {
516 "type": "array",
517 "items": {
518 "$ref": "#/components/schemas/Book"
519 }
520 }
521 }
522 }
523 },
524 "400": {
525 "description": "Invalid query parameter",
526 "content": {
527 "application/json": {
528 "schema": {
529 "$ref": "#/components/schemas/BookErrorResponse"
530 }
531 }
532 }
533 },
534 "500": {
535 "description": "Internal server error",
536 "content": {
537 "application/json": {
538 "schema": {
539 "$ref": "#/components/schemas/InternalServerError"
540 }
541 }
542 }
543 }
544 }
545 }
546 },
547 "/{isbn}": {
548 "parameters": [
549 {
550 "$ref": "#/components/parameters/ISBNPathParam"
551 }
552 ],
553 "get": {
554 "summary": "Get a book by ISBN",
555 "operationId": "getBookByISBN",
556 "responses": {
557 "200": {
558 "description": "Book found",
559 "content": {
560 "application/json": {
561 "schema": {
562 "$ref": "#/components/schemas/Book"
563 }
564 }
565 }
566 },
567 "400": {
568 "description": "Invalid ISBN format",
569 "content": {
570 "application/json": {
571 "schema": {
572 "type": "object",
573 "properties": {
574 "error": {
575 "type": "string",
576 "example": "BookError: Invalid book id (9783161484100) [must be ISBN-13 formatted]"
577 }
578 }
579 }
580 }
581 }
582 },
583 "404": {
584 "description": "Book not found",
585 "content": {
586 "application/json": {
587 "schema": {
588 "type": "object",
589 "properties": {
590 "error": {
591 "type": "string",
592 "example": "BookError: Book 9783161484100 not found"
593 }
594 }
595 }
596 }
597 }
598 }
599 }
600 },
601 "patch": {
602 "summary": "Update a book",
603 "operationId": "updateBook",
604 "security": [
605 {
606 "ApiKeyAuth": []
607 }
608 ],
609 "requestBody": {
610 "required": true,
611 "content": {
612 "application/json": {
613 "schema": {
614 "$ref": "#/components/schemas/PartialBook"
615 }
616 }
617 }
618 },
619 "responses": {
620 "204": {
621 "description": "Book updated successfully (no content)"
622 },
623 "400": {
624 "description": "Invalid book data or ISBN format",
625 "content": {
626 "application/json": {
627 "schema": {
628 "$ref": "#/components/schemas/BookErrorResponse"
629 }
630 }
631 }
632 },
633 "401": {
634 "description": "Unauthorized - invalid or missing API key",
635 "content": {
636 "application/json": {
637 "schema": {
638 "type": "object",
639 "properties": {
640 "error": {
641 "type": "string",
642 "example": "Unauthorized"
643 }
644 }
645 }
646 }
647 }
648 },
649 "404": {
650 "description": "Book not found",
651 "content": {
652 "application/json": {
653 "schema": {
654 "type": "object",
655 "properties": {
656 "error": {
657 "type": "string",
658 "example": "BookError: Book 9783161484100 not found"
659 }
660 }
661 }
662 }
663 }
664 },
665 "500": {
666 "description": "Internal server error",
667 "content": {
668 "application/json": {
669 "schema": {
670 "$ref": "#/components/schemas/InternalServerError"
671 }
672 }
673 }
674 }
675 }
676 },
677 "delete": {
678 "summary": "Delete a book",
679 "operationId": "deleteBook",
680 "security": [
681 {
682 "ApiKeyAuth": []
683 }
684 ],
685 "responses": {
686 "204": {
687 "description": "Book deleted successfully (no content)"
688 },
689 "401": {
690 "description": "Unauthorized - invalid or missing API key",
691 "content": {
692 "application/json": {
693 "schema": {
694 "type": "object",
695 "properties": {
696 "error": {
697 "type": "string",
698 "example": "Unauthorized"
699 }
700 }
701 }
702 }
703 }
704 },
705 "404": {
706 "description": "Book not found",
707 "content": {
708 "application/json": {
709 "schema": {
710 "type": "object",
711 "properties": {
712 "error": {
713 "type": "string",
714 "example": "BookError: Book 9783161484100 not found"
715 }
716 }
717 }
718 }
719 }
720 },
721 "500": {
722 "description": "Internal server error",
723 "content": {
724 "application/json": {
725 "schema": {
726 "$ref": "#/components/schemas/InternalServerError"
727 }
728 }
729 }
730 }
731 }
732 }
733 }
734 },
735 "security": []
736}