├── README.md
├── ch01
└── dog.yaml
├── ch06
├── 01.yml
├── f02.yml
└── openapi.yaml
├── ch07
├── 01.yml
└── openapi.yml
├── ch08
├── 01.yml
├── 02.yml
├── markdown-cheatsheet.yml
├── openapi.yml
└── site
│ ├── index.html
│ ├── openapi.yml
│ └── site.zip
├── ch10
├── 01.yml
├── README.md
└── openapi.yml
├── ch11
├── README.md
└── openapi.yml
├── ch12
├── 01.yml
├── 02.yml
├── 03.yml
├── README.md
└── openapi.yml
├── ch13
├── 01.yml
├── 02.yml
├── README.md
└── openapi.yml
├── ch14
├── 01.yml
├── README.md
└── openapi.yml
├── ch16
├── README.md
└── openapi.yaml
├── ch17
├── README.md
└── openapi.yaml
├── ch18
├── README.md
└── openapi.yaml
├── ch19
├── README.md
└── openapi.yaml
├── ch20
├── README.md
└── openapi.yml
└── core-concept
└── openapi.yml
/README.md:
--------------------------------------------------------------------------------
1 | # openapi
2 | The supporting OpenAPI documents for Designing APIs with Swagger and OpenAPI
3 |
--------------------------------------------------------------------------------
/ch01/dog.yaml:
--------------------------------------------------------------------------------
1 | openapi: 3.0.3
2 | info:
3 | title: Dog API
4 | version: '1.0.0'
5 | servers:
6 | - url: https://dog.ceo/api
7 | paths:
8 | /breed/{breedName}/images:
9 | get:
10 | description: Get images of dog breeds
11 | parameters:
12 | - in: path
13 | name: breedName
14 | schema:
15 | type: string
16 | example: hound
17 | required: true
18 | responses:
19 | '200':
20 | description: A list of dog images
21 | content:
22 | application/json:
23 | schema:
24 | type: object
25 | properties:
26 | status:
27 | type: string
28 | example: success
29 | message:
30 | type: array
31 | items:
32 | type: string
33 | example: https://images.dog.ceo/breeds/hound-afghan/n02088094_1003.jpg
34 |
--------------------------------------------------------------------------------
/ch06/01.yml:
--------------------------------------------------------------------------------
1 | openapi: 3.0.3
2 | info:
3 | version: v1
4 | title: FarmStall API
5 | servers:
6 | - url: https://farmstall.designapis.com/v1
7 | paths:
8 | /reviews:
9 | post:
10 | description: Create a new Review
11 | requestBody:
12 | description: A new Review
13 | content:
14 | application/json:
15 | schema:
16 | type: object
17 | properties:
18 | message:
19 | type: string
20 | rating:
21 | type: integer
22 | minimum: 1
23 | maximum: 5
24 | userId:
25 | type: string
26 | pattern: '^[0-9a-fA-F\-]{36}$'
27 | nullable: true
28 | responses:
29 | '201':
30 | description: Successfully created a new Review
31 | content:
32 | application/json:
33 | schema:
34 | type: object
35 | properties:
36 | message:
37 | type: string
38 | rating:
39 | type: integer
40 | minimum: 1
41 | maximum: 5
42 | userId:
43 | type: string
44 | nullable: true
45 | pattern: '^[0-9a-fA-F\-]{36}$'
46 | uuid:
47 | type: string
48 | pattern: '^[0-9a-fA-F\-]{36}$'
49 |
50 |
--------------------------------------------------------------------------------
/ch06/f02.yml:
--------------------------------------------------------------------------------
1 | openapi: 3.0.3
2 | info:
3 | version: v1
4 | title: FarmStall API
5 | servers:
6 | - url: https://farmstall.designapis.com/v1
7 | paths:
8 | /reviews:
9 | # get: ...
10 | post:
11 | description: Create a new Review
12 | requestBody:
13 | description: A new Review
14 | content:
15 | application/json:
16 | schema:
17 | type: object
18 | properties:
19 | message:
20 | type: string
21 | rating:
22 | type: integer
23 | minimum: 1
24 | maximum: 5
25 | userId:
26 | type: string
27 | pattern: '^[0-9a-fA-F\-]{36}$'
28 | nullable: true
29 | responses:
30 | '201':
31 | description: Successfully created a new Review
32 | content:
33 | application/json:
34 | schema:
35 | type: object
36 | properties:
37 | message:
38 | type: string
39 | example: An awesome time for the whole family.
40 | rating:
41 | type: integer
42 | minimum: 1
43 | maximum: 5
44 | userId:
45 | type: string
46 | nullable: true
47 | pattern: '^[0-9a-fA-F\-]{36}$'
48 | uuid:
49 | type: string
50 | pattern: '^[0-9a-fA-F\-]{36}$'
51 | /reviews/{reviewId}:
52 | get:
53 | description: Get a single review
54 | parameters:
55 | - name: reviewId
56 | in: path
57 | required: true
58 | schema:
59 | type: string
60 | description: The review's ID
61 | example: 3b5b1707-b82c-4b1d-9078-157053902525
62 | minLength: 36
63 | maxLength: 36
64 | pattern: '[a-zA-Z0-9-]+'
65 | responses:
66 | '200':
67 | description: A single review
68 | content:
69 | application/json:
70 | schema:
71 | type: object
72 | properties:
73 | message:
74 | type: string
75 | rating:
76 | type: integer
77 | minimum: 1
78 | maximum: 5
79 | userId:
80 | minLength: 36
81 | maxLength: 36
82 | pattern: '^[a-zA-Z0-9-]+$'
83 | nullable: true
84 | uuid:
85 | minLength: 36
86 | maxLength: 36
87 | pattern: '^[a-zA-Z0-9-]+$'
88 |
--------------------------------------------------------------------------------
/ch06/openapi.yaml:
--------------------------------------------------------------------------------
1 | openapi: 3.0.3
2 | info:
3 | version: v1
4 | title: FarmStall API
5 | servers:
6 | - url: https://farmstall.designapis.com/v1
7 | paths:
8 | /reviews:
9 | get:
10 | description: Get a list of reviews
11 | parameters:
12 | - name: maxRating
13 | in: query
14 | schema:
15 | type: number
16 | responses:
17 | '200':
18 | description: A bunch of reviews
19 | content:
20 | application/json:
21 | schema:
22 | type: array
23 | items:
24 | type: object
25 | properties:
26 | rating:
27 | type: integer
28 | minimum: 1
29 | maximum: 5
30 | message:
31 | type: string
32 | example: An awesome time for the whole family.
33 | uuid:
34 | type: string
35 | pattern: '^[0-9a-fA-F\-]{36}$'
36 | example: 3b5b1707-b82c-4b1d-9078-157053902525
37 | userId:
38 | type: string
39 | pattern: '^[0-9a-fA-F\-]{36}$'
40 | nullable: true
41 | example: 3b5b1707-b82c-4b1d-9078-157053902525
42 | post:
43 | description: Create a new Review
44 | requestBody:
45 | description: A new Review
46 | content:
47 | application/json:
48 | schema:
49 | type: object
50 | properties:
51 | message:
52 | type: string
53 | example: An awesome time for the whole family.
54 | rating:
55 | type: integer
56 | example: 5
57 | minimum: 1
58 | maximum: 5
59 | userId:
60 | type: string
61 | pattern: '^[0-9a-fA-F\-]{36}$'
62 | nullable: true
63 | example: null
64 | responses:
65 | '201':
66 | description: Successfully created a new Review
67 | content:
68 | application/json:
69 | schema:
70 | type: object
71 | properties:
72 | message:
73 | type: string
74 | example: An awesome time for the whole family.
75 | rating:
76 | type: integer
77 | example: 5
78 | minimum: 1
79 | maximum: 5
80 | userId:
81 | type: string
82 | nullable: true
83 | pattern: '^[0-9a-fA-F\-]{36}$'
84 | example: 3b5b1707-b82c-4b1d-9078-157053902525
85 | uuid:
86 | type: string
87 | pattern: '^[0-9a-fA-F\-]{36}$'
88 | example: 3b5b1707-b82c-4b1d-9078-157053902525
89 | /reviews/{reviewId}:
90 | get:
91 | description: Get a single review
92 | parameters:
93 | - name: reviewId
94 | in: path
95 | required: true
96 | schema:
97 | type: string
98 | description: The review's ID
99 | example: 3b5b1707-b82c-4b1d-9078-157053902525
100 | minLength: 36
101 | maxLength: 36
102 | pattern: '[a-zA-Z0-9-]+'
103 | responses:
104 | '200':
105 | description: A single review
106 | content:
107 | application/json:
108 | schema:
109 | type: object
110 | properties:
111 | message:
112 | type: string
113 | example: 3b5b1707-b82c-4b1d-9078-157053902525
114 | rating:
115 | type: integer
116 | example: 5
117 | minimum: 1
118 | maximum: 5
119 | userId:
120 | minLength: 36
121 | maxLength: 36
122 | pattern: '^[a-zA-Z0-9-]+$'
123 | nullable: true
124 | example: 3b5b1707-b82c-4b1d-9078-157053902525
125 | uuid:
126 | minLength: 36
127 | maxLength: 36
128 | pattern: '^[a-zA-Z0-9-]+$'
129 | example: 3b5b1707-b82c-4b1d-9078-157053902525
130 |
--------------------------------------------------------------------------------
/ch07/01.yml:
--------------------------------------------------------------------------------
1 | openapi: 3.0.3
2 | info:
3 | version: v1
4 | title: FarmStall API
5 | servers:
6 | - url: https://farmstall.designapis.com/v1
7 | paths:
8 | /reviews:
9 | get:
10 | description: Get a list of reviews
11 | parameters:
12 | - name: maxRating
13 | in: query
14 | schema:
15 | type: number
16 | responses:
17 | '200':
18 | description: A bunch of reviews
19 | content:
20 | application/json:
21 | schema:
22 | type: array
23 | items:
24 | type: object
25 | properties:
26 | rating:
27 | type: integer
28 | minimum: 1
29 | maximum: 5
30 | message:
31 | type: string
32 | example: An awesome time for the whole family.
33 | uuid:
34 | type: string
35 | pattern: '^[0-9a-fA-F\-]{36}$'
36 | example: 3b5b1707-b82c-4b1d-9078-157053902525
37 | userId:
38 | type: string
39 | pattern: '^[0-9a-fA-F\-]{36}$'
40 | nullable: true
41 | example: 3b5b1707-b82c-4b1d-9078-157053902525
42 | post:
43 | description: Create a new Review
44 | requestBody:
45 | description: A new Review
46 | content:
47 | application/json:
48 | schema:
49 | type: object
50 | properties:
51 | message:
52 | type: string
53 | example: An awesome time for the whole family.
54 | rating:
55 | type: integer
56 | example: 5
57 | minimum: 1
58 | maximum: 5
59 | userId:
60 | type: string
61 | pattern: '^[0-9a-fA-F\-]{36}$'
62 | nullable: true
63 | example: null
64 | responses:
65 | '201':
66 | description: Successfully created a new Review
67 | content:
68 | application/json:
69 | schema:
70 | type: object
71 | properties:
72 | message:
73 | type: string
74 | example: An awesome time for the whole family.
75 | rating:
76 | type: integer
77 | example: 5
78 | minimum: 1
79 | maximum: 5
80 | userId:
81 | type: string
82 | nullable: true
83 | pattern: '^[0-9a-fA-F\-]{36}$'
84 | example: 3b5b1707-b82c-4b1d-9078-157053902525
85 | uuid:
86 | type: string
87 | pattern: '^[0-9a-fA-F\-]{36}$'
88 | example: 3b5b1707-b82c-4b1d-9078-157053902525
89 | /reviews/{reviewId}:
90 | get:
91 | description: Get a single review
92 | parameters:
93 | - name: reviewId
94 | in: path
95 | required: true
96 | schema:
97 | type: string
98 | description: The review's ID
99 | example: 3b5b1707-b82c-4b1d-9078-157053902525
100 | minLength: 36
101 | maxLength: 36
102 | pattern: '[a-zA-Z0-9-]+'
103 | responses:
104 | '200':
105 | description: A single review
106 | content:
107 | application/json:
108 | schema:
109 | type: object
110 | properties:
111 | message:
112 | type: string
113 | example: 3b5b1707-b82c-4b1d-9078-157053902525
114 | rating:
115 | type: integer
116 | example: 5
117 | minimum: 1
118 | maximum: 5
119 | userId:
120 | minLength: 36
121 | maxLength: 36
122 | pattern: '^[a-zA-Z0-9-]+$'
123 | nullable: true
124 | example: 3b5b1707-b82c-4b1d-9078-157053902525
125 | uuid:
126 | minLength: 36
127 | maxLength: 36
128 | pattern: '^[a-zA-Z0-9-]+$'
129 | example: 3b5b1707-b82c-4b1d-9078-157053902525
130 |
--------------------------------------------------------------------------------
/ch07/openapi.yml:
--------------------------------------------------------------------------------
1 | openapi: 3.0.3
2 | info:
3 | version: v1
4 | title: FarmStall API
5 | servers:
6 | - url: https://farmstall.designapis.com/v1
7 | paths:
8 | /reviews:
9 | get:
10 | description: Get a list of reviews
11 | parameters:
12 | - name: maxRating
13 | in: query
14 | schema:
15 | type: number
16 | responses:
17 | '200':
18 | description: A bunch of reviews
19 | content:
20 | application/json:
21 | schema:
22 | type: array
23 | items:
24 | type: object
25 | properties:
26 | rating:
27 | type: integer
28 | minimum: 1
29 | maximum: 5
30 | message:
31 | type: string
32 | example: An awesome time for the whole family.
33 | uuid:
34 | type: string
35 | pattern: '^[0-9a-fA-F\-]{36}$'
36 | example: 3b5b1707-b82c-4b1d-9078-157053902525
37 | userId:
38 | type: string
39 | pattern: '^[0-9a-fA-F\-]{36}$'
40 | nullable: true
41 | example: 3b5b1707-b82c-4b1d-9078-157053902525
42 | post:
43 | description: Create a new Review
44 | security:
45 | - MyUserToken: []
46 | requestBody:
47 | description: A new Review
48 | content:
49 | application/json:
50 | schema:
51 | type: object
52 | properties:
53 | message:
54 | type: string
55 | example: An awesome time for the whole family.
56 | rating:
57 | type: integer
58 | example: 5
59 | minimum: 1
60 | maximum: 5
61 | responses:
62 | '201':
63 | description: Successfully created a new Review
64 | content:
65 | application/json:
66 | schema:
67 | type: object
68 | properties:
69 | message:
70 | type: string
71 | example: An awesome time for the whole family.
72 | rating:
73 | type: integer
74 | example: 5
75 | minimum: 1
76 | maximum: 5
77 | userId:
78 | type: string
79 | nullable: true
80 | pattern: '^[0-9a-fA-F\-]{36}$'
81 | example: 3b5b1707-b82c-4b1d-9078-157053902525
82 | uuid:
83 | type: string
84 | pattern: '^[0-9a-fA-F\-]{36}$'
85 | example: 3b5b1707-b82c-4b1d-9078-157053902525
86 | /reviews/{reviewId}:
87 | get:
88 | description: Get a single review
89 | parameters:
90 | - name: reviewId
91 | in: path
92 | required: true
93 | schema:
94 | type: string
95 | description: The review's ID
96 | example: 3b5b1707-b82c-4b1d-9078-157053902525
97 | minLength: 36
98 | maxLength: 36
99 | pattern: '[a-zA-Z0-9-]+'
100 | responses:
101 | '200':
102 | description: A single review
103 | content:
104 | application/json:
105 | schema:
106 | type: object
107 | properties:
108 | message:
109 | type: string
110 | example: An awesome time for the whole family.
111 | rating:
112 | type: integer
113 | example: 5
114 | minimum: 1
115 | maximum: 5
116 | userId:
117 | minLength: 36
118 | maxLength: 36
119 | pattern: '^[a-zA-Z0-9-]+$'
120 | nullable: true
121 | example: 3b5b1707-b82c-4b1d-9078-157053902525
122 | uuid:
123 | minLength: 36
124 | maxLength: 36
125 | pattern: '^[a-zA-Z0-9-]+$'
126 | example: 3b5b1707-b82c-4b1d-9078-157053902525
127 | /users:
128 | post:
129 | description: Create a new user
130 | requestBody:
131 | description: User details
132 | content:
133 | application/json:
134 | schema:
135 | type: object
136 | properties:
137 | username:
138 | type: string
139 | example: ponelat
140 | password:
141 | type: string
142 | format: password
143 | fullName:
144 | type: string
145 | example: Josh Ponelat
146 | responses:
147 | '201':
148 | description: Successfully created a new user
149 | content:
150 | application/json:
151 | schema:
152 | type: object
153 | properties:
154 | username:
155 | type: string
156 | example: ponelat
157 | uuid:
158 | type: string
159 | example: f7f680a8-d111-421f-b6b3-493ebf905078
160 | /tokens:
161 | post:
162 | description: Create a new token
163 | requestBody:
164 | content:
165 | application/json:
166 | schema:
167 | type: object
168 | properties:
169 | username:
170 | type: string
171 | example: ponelat
172 | password:
173 | type: string
174 | format: password
175 |
176 | responses:
177 | '201':
178 | description: Create a new token for gaining authenticated access to resources
179 | content:
180 | application/json:
181 | schema:
182 | type: object
183 | properties:
184 | token:
185 | type: string
186 |
187 | components:
188 | securitySchemes:
189 | MyUserToken:
190 | type: apiKey
191 | in: header
192 | name: Authorization
193 |
--------------------------------------------------------------------------------
/ch08/01.yml:
--------------------------------------------------------------------------------
1 | openapi: 3.0.3
2 | info:
3 | version: v1
4 | title: FarmStall API
5 | servers:
6 | - url: https://farmstall.designapis.com/v1
7 | paths:
8 | /reviews:
9 | get:
10 | description: Get a list of reviews
11 | parameters:
12 | - name: maxRating
13 | in: query
14 | schema:
15 | type: number
16 | responses:
17 | '200':
18 | description: A bunch of reviews
19 | content:
20 | application/json:
21 | schema:
22 | type: array
23 | items:
24 | type: object
25 | properties:
26 | rating:
27 | type: integer
28 | minimum: 1
29 | maximum: 5
30 | message:
31 | type: string
32 | example: An awesome time for the whole family.
33 | uuid:
34 | type: string
35 | pattern: '^[0-9a-fA-F\-]{36}$'
36 | example: 3b5b1707-b82c-4b1d-9078-157053902525
37 | userId:
38 | type: string
39 | pattern: '^[0-9a-fA-F\-]{36}$'
40 | nullable: true
41 | example: 3b5b1707-b82c-4b1d-9078-157053902525
42 | post:
43 | description: Create a new Review
44 | security:
45 | - MyUserToken: []
46 | requestBody:
47 | description: A new Review
48 | content:
49 | application/json:
50 | schema:
51 | type: object
52 | properties:
53 | message:
54 | type: string
55 | example: An awesome time for the whole family.
56 | rating:
57 | type: integer
58 | example: 5
59 | minimum: 1
60 | maximum: 5
61 | responses:
62 | '201':
63 | description: Successfully created a new Review
64 | content:
65 | application/json:
66 | schema:
67 | type: object
68 | properties:
69 | message:
70 | type: string
71 | example: An awesome time for the whole family.
72 | rating:
73 | type: integer
74 | example: 5
75 | minimum: 1
76 | maximum: 5
77 | userId:
78 | type: string
79 | nullable: true
80 | pattern: '^[0-9a-fA-F\-]{36}$'
81 | example: 3b5b1707-b82c-4b1d-9078-157053902525
82 | uuid:
83 | type: string
84 | pattern: '^[0-9a-fA-F\-]{36}$'
85 | example: 3b5b1707-b82c-4b1d-9078-157053902525
86 | /reviews/{reviewId}:
87 | get:
88 | description: Get a single review
89 | parameters:
90 | - name: reviewId
91 | in: path
92 | required: true
93 | schema:
94 | type: string
95 | description: The review's ID
96 | example: 3b5b1707-b82c-4b1d-9078-157053902525
97 | minLength: 36
98 | maxLength: 36
99 | pattern: '[a-zA-Z0-9-]+'
100 | responses:
101 | '200':
102 | description: A single review
103 | content:
104 | application/json:
105 | schema:
106 | type: object
107 | properties:
108 | message:
109 | type: string
110 | example: An awesome time for the whole family.
111 | rating:
112 | type: integer
113 | example: 5
114 | minimum: 1
115 | maximum: 5
116 | userId:
117 | minLength: 36
118 | maxLength: 36
119 | pattern: '^[a-zA-Z0-9-]+$'
120 | nullable: true
121 | example: 3b5b1707-b82c-4b1d-9078-157053902525
122 | uuid:
123 | minLength: 36
124 | maxLength: 36
125 | pattern: '^[a-zA-Z0-9-]+$'
126 | example: 3b5b1707-b82c-4b1d-9078-157053902525
127 | /users:
128 | post:
129 | description: Create a new user
130 | requestBody:
131 | description: User details
132 | content:
133 | application/json:
134 | schema:
135 | type: object
136 | properties:
137 | username:
138 | type: string
139 | example: ponelat
140 | password:
141 | type: string
142 | format: password
143 | fullName:
144 | type: string
145 | example: Josh Ponelat
146 | responses:
147 | '201':
148 | description: Successfully created a new user
149 | content:
150 | application/json:
151 | schema:
152 | type: object
153 | properties:
154 | username:
155 | type: string
156 | example: ponelat
157 | uuid:
158 | type: string
159 | example: f7f680a8-d111-421f-b6b3-493ebf905078
160 | /tokens:
161 | post:
162 | description: Create a new token
163 | requestBody:
164 | content:
165 | application/json:
166 | schema:
167 | type: object
168 | properties:
169 | username:
170 | type: string
171 | example: ponelat
172 | password:
173 | type: string
174 | format: password
175 |
176 | responses:
177 | '201':
178 | description: Create a new token for gaining authenticated access to resources
179 | content:
180 | application/json:
181 | schema:
182 | type: object
183 | properties:
184 | token:
185 | type: string
186 |
187 | components:
188 | securitySchemes:
189 | MyUserToken:
190 | type: apiKey
191 | in: header
192 | name: Authorization
193 |
--------------------------------------------------------------------------------
/ch08/02.yml:
--------------------------------------------------------------------------------
1 | openapi: 3.0.3
2 | info:
3 | version: v1
4 | title: FarmStall API
5 | description: |-
6 |
7 | An API for writing reviews about your favourite (or worst) farm stalls.
8 |
9 | 
10 |
11 | ---
12 |
13 | # Auth
14 |
15 | To create **Reviews** without being _anonymous_. You need to add a **MyUserToken** to the `Authorization` header.
16 |
17 | To get a **MyUserToken**:
18 | 1. Create a **User** with [POST /users](#Users/post_users)
19 | 1. Get a **MyUserToken** by calling [POST /tokens](#Users/post_tokens) with your **User** credentials.
20 |
21 | # Reviews
22 | Reviews are the heart of this API.
23 | Registered **Users** and anonymous users can both write reviews based on their experience at farm stalls.
24 |
25 | Each review comes with a rating of between one and five stars inclusive.
26 |
27 | - One star being the worst experience
28 | - Five stars being the best
29 |
30 |
31 | ### Example Reviews
32 |
33 | "A wonderful time!" — Bob McNally
34 |
35 | 
36 |
37 | "An awful place" — _Anonymous_
38 |
39 | 
40 |
41 | "A totally average place." — Jane Fair
42 |
43 | 
44 |
45 | contact:
46 | name: Josh Ponelat
47 | email: jponelat+daso@gmail.com
48 | url: https://farmstall.designapis.com
49 | license:
50 | url: https://www.apache.org/licenses/LICENSE-2.0
51 | name: Apache 2.0
52 | externalDocs:
53 | url: https://farmstall.designapis.com
54 | description: Hosted docs
55 | servers:
56 | - url: https://farmstall.designapis.com/v1
57 | paths:
58 | /reviews:
59 | get:
60 | description: Get a list of reviews
61 | parameters:
62 | - name: maxRating
63 | in: query
64 | schema:
65 | type: number
66 | responses:
67 | '200':
68 | description: A bunch of reviews
69 | content:
70 | application/json:
71 | schema:
72 | type: array
73 | items:
74 | type: object
75 | properties:
76 | rating:
77 | type: integer
78 | minimum: 1
79 | maximum: 5
80 | message:
81 | type: string
82 | example: An awesome time for the whole family.
83 | uuid:
84 | type: string
85 | pattern: '^[0-9a-fA-F\-]{36}$'
86 | example: 3b5b1707-b82c-4b1d-9078-157053902525
87 | userId:
88 | type: string
89 | pattern: '^[0-9a-fA-F\-]{36}$'
90 | nullable: true
91 | example: 3b5b1707-b82c-4b1d-9078-157053902525
92 | post:
93 | description: Create a new Review
94 | security:
95 | - MyUserToken: []
96 | requestBody:
97 | description: A new Review
98 | content:
99 | application/json:
100 | schema:
101 | type: object
102 | properties:
103 | message:
104 | type: string
105 | example: An awesome time for the whole family.
106 | rating:
107 | type: integer
108 | example: 5
109 | minimum: 1
110 | maximum: 5
111 | responses:
112 | '201':
113 | description: Successfully created a new Review
114 | content:
115 | application/json:
116 | schema:
117 | type: object
118 | properties:
119 | message:
120 | type: string
121 | example: An awesome time for the whole family.
122 | rating:
123 | type: integer
124 | example: 5
125 | minimum: 1
126 | maximum: 5
127 | userId:
128 | type: string
129 | nullable: true
130 | pattern: '^[0-9a-fA-F\-]{36}$'
131 | example: 3b5b1707-b82c-4b1d-9078-157053902525
132 | uuid:
133 | type: string
134 | pattern: '^[0-9a-fA-F\-]{36}$'
135 | example: 3b5b1707-b82c-4b1d-9078-157053902525
136 | /reviews/{reviewId}:
137 | get:
138 | description: Get a single review
139 | parameters:
140 | - name: reviewId
141 | in: path
142 | required: true
143 | schema:
144 | type: string
145 | description: The review's ID
146 | example: 3b5b1707-b82c-4b1d-9078-157053902525
147 | minLength: 36
148 | maxLength: 36
149 | pattern: '[a-zA-Z0-9-]+'
150 | responses:
151 | '200':
152 | description: A single review
153 | content:
154 | application/json:
155 | schema:
156 | type: object
157 | properties:
158 | message:
159 | type: string
160 | example: An awesome time for the whole family.
161 | rating:
162 | type: integer
163 | example: 5
164 | minimum: 1
165 | maximum: 5
166 | userId:
167 | minLength: 36
168 | maxLength: 36
169 | pattern: '^[a-zA-Z0-9-]+$'
170 | nullable: true
171 | example: 3b5b1707-b82c-4b1d-9078-157053902525
172 | uuid:
173 | minLength: 36
174 | maxLength: 36
175 | pattern: '^[a-zA-Z0-9-]+$'
176 | example: 3b5b1707-b82c-4b1d-9078-157053902525
177 | /users:
178 | post:
179 | description: Create a new user
180 | requestBody:
181 | description: User details
182 | content:
183 | application/json:
184 | schema:
185 | type: object
186 | properties:
187 | username:
188 | type: string
189 | example: ponelat
190 | password:
191 | type: string
192 | format: password
193 | fullName:
194 | type: string
195 | example: Josh Ponelat
196 | responses:
197 | '201':
198 | description: Successfully created a new user
199 | content:
200 | application/json:
201 | schema:
202 | type: object
203 | properties:
204 | username:
205 | type: string
206 | example: ponelat
207 | uuid:
208 | type: string
209 | example: f7f680a8-d111-421f-b6b3-493ebf905078
210 | /tokens:
211 | post:
212 | description: Create a new token
213 | requestBody:
214 | content:
215 | application/json:
216 | schema:
217 | type: object
218 | properties:
219 | username:
220 | type: string
221 | example: ponelat
222 | password:
223 | type: string
224 | format: password
225 |
226 | responses:
227 | '201':
228 | description: Create a new token for gaining authenticated access to resources
229 | content:
230 | application/json:
231 | schema:
232 | type: object
233 | properties:
234 | token:
235 | type: string
236 |
237 | components:
238 | securitySchemes:
239 | MyUserToken:
240 | type: apiKey
241 | in: header
242 | name: Authorization
243 |
--------------------------------------------------------------------------------
/ch08/markdown-cheatsheet.yml:
--------------------------------------------------------------------------------
1 | openapi: 3.0.3
2 | info:
3 | version: v1
4 | title: FarmStall API
5 | description: |-
6 | *\*italic\**
7 |
8 |
9 | **\*\*bold\*\***
10 |
11 |
12 | _\_Mix of italic and **\*\*bold\*\***\__
13 |
14 | > \> Block quote
15 |
16 | # \# Heading 1
17 |
18 |
19 | ## \#\# Heading 2
20 |
21 |
22 | ### \#\#\# Heading 3
23 |
24 | [\[A link\]\(https://example.com\)]()
25 |
26 |
27 | \![An image]\(/img/rating-5.png)
28 | 
29 |
30 | \* unordered list
31 | \* two
32 | \* three
33 |
34 | 1\. numbered list
35 | 1\. two
36 | 1\. three
37 |
38 | \--- (horizontal line)
39 |
40 | ---
41 |
42 |
43 | ```
44 | A code block
45 | ```
46 |
47 |
48 | paths: {}
49 |
--------------------------------------------------------------------------------
/ch08/openapi.yml:
--------------------------------------------------------------------------------
1 | openapi: 3.0.3
2 | info:
3 | version: v1
4 | title: FarmStall API
5 | description: |-
6 |
7 | An API for writing reviews about your favourite (or worst) farm stalls.
8 |
9 | 
10 |
11 | ---
12 |
13 | # Auth
14 |
15 | To create **Reviews** without being _anonymous_. You need to add a **MyUserToken** to the `Authorization` header.
16 |
17 | To get a **MyUserToken**:
18 | 1. Create a **User** with [POST /users](#Users/post_users)
19 | 1. Get a **MyUserToken** by calling [POST /tokens](#Users/post_tokens) with your **User** credentials.
20 |
21 | # Reviews
22 | Reviews are the heart of this API.
23 | Registered **Users** and anonymous users can both write reviews based on their experience at farm stalls.
24 |
25 | Each review comes with a rating of between one and five stars inclusive.
26 |
27 | - One star being the worst experience
28 | - Five stars being the best
29 |
30 |
31 | ### Example Reviews
32 |
33 | "A wonderful time!" — Bob McNally
34 |
35 | 
36 |
37 | "An awful place" — _Anonymous_
38 |
39 | 
40 |
41 | "A totally average place." — Jane Fair
42 |
43 | 
44 |
45 | contact:
46 | name: Josh Ponelat
47 | email: jponelat+daso@gmail.com
48 | url: https://farmstall.designapis.com
49 |
50 | license:
51 | url: https://www.apache.org/licenses/LICENSE-2.0
52 | name: Apache 2.0
53 |
54 | externalDocs:
55 | url: https://farmstall.designapis.com
56 | description: Hosted docs
57 |
58 | tags:
59 | - name: Reviews
60 | description: Reviews of your favourite/worst farm stalls
61 |
62 | - name: Users
63 | description: Users and authentication
64 |
65 | servers:
66 | - url: 'https://farmstall.designapis.com/v1'
67 |
68 | paths:
69 | /reviews:
70 | get:
71 | tags:
72 | - Reviews
73 | description: Get a list of reviews
74 | parameters:
75 | - name: maxRating
76 | in: query
77 | schema:
78 | type: number
79 | responses:
80 | '200':
81 | description: A bunch of reviews
82 | content:
83 | application/json:
84 | schema:
85 | type: array
86 | items:
87 | type: object
88 | properties:
89 | rating:
90 | type: integer
91 | minimum: 1
92 | maximum: 5
93 | message:
94 | type: string
95 | example: An awesome time for the whole family.
96 | uuid:
97 | type: string
98 | pattern: '^[0-9a-fA-F\-]{36}$'
99 | example: 3b5b1707-b82c-4b1d-9078-157053902525
100 | userId:
101 | type: string
102 | pattern: '^[0-9a-fA-F\-]{36}$'
103 | nullable: true
104 | example: 3b5b1707-b82c-4b1d-9078-157053902525
105 |
106 | post:
107 | tags:
108 | - Reviews
109 | description: Create a new Review
110 | security:
111 | - MyUserToken: []
112 | requestBody:
113 | description: A new Review
114 | content:
115 | application/json:
116 | schema:
117 | type: object
118 | properties:
119 | message:
120 | type: string
121 | example: An awesome time for the whole family.
122 | rating:
123 | type: integer
124 | minimum: 1
125 | maximum: 5
126 | example: 5
127 | responses:
128 | '201':
129 | description: Successfully created a new Review
130 | content:
131 | application/json:
132 | schema:
133 | type: object
134 | properties:
135 | message:
136 | type: string
137 | example: An awesome time for the whole family.
138 | rating:
139 | type: integer
140 | minimum: 1
141 | maximum: 5
142 | example: 5
143 | userId:
144 | type: string
145 | nullable: true
146 | pattern: '^[0-9a-fA-F\-]{36}$'
147 | example: 3b5b1707-b82c-4b1d-9078-157053902525
148 | uuid:
149 | type: string
150 | pattern: '^[0-9a-fA-F\-]{36}$'
151 | example: 3b5b1707-b82c-4b1d-9078-157053902525
152 |
153 |
154 | /reviews/{reviewId}:
155 | get:
156 | tags:
157 | - Reviews
158 | description: Get a single review
159 | parameters:
160 | - name: reviewId
161 | in: path
162 | required: true
163 | schema:
164 | type: string
165 | description: The review's ID
166 | example: 3b5b1707-b82c-4b1d-9078-157053902525
167 | minLength: 36
168 | maxLength: 36
169 | pattern: '[a-zA-Z0-9-]+'
170 | responses:
171 | '200':
172 | description: A single review
173 | content:
174 | application/json:
175 | schema:
176 | type: object
177 | properties:
178 | message:
179 | type: string
180 | example: An awesome time for the whole family.
181 | rating:
182 | type: integer
183 | minimum: 1
184 | maximum: 5
185 | example: 5
186 | userId:
187 | minLength: 36
188 | maxLength: 36
189 | pattern: '^[a-zA-Z0-9-]+$'
190 | nullable: true
191 | example: 3b5b1707-b82c-4b1d-9078-157053902525
192 | uuid:
193 | minLength: 36
194 | maxLength: 36
195 | pattern: '^[a-zA-Z0-9-]+$'
196 | example: 3b5b1707-b82c-4b1d-9078-157053902525
197 | '404':
198 | description: Review not found
199 |
200 |
201 |
202 | /users:
203 | post:
204 | tags:
205 | - Users
206 | description: Create a new user
207 | requestBody:
208 | description: User details
209 | content:
210 | application/json:
211 | schema:
212 | type: object
213 | properties:
214 | username:
215 | type: string
216 | example: ponelat
217 | password:
218 | type: string
219 | format: password
220 | fullName:
221 | type: string
222 | example: Josh Ponelat
223 | responses:
224 | '201':
225 | description: Successfully created a new user
226 | content:
227 | application/json:
228 | schema:
229 | type: object
230 | properties:
231 | username:
232 | type: string
233 | example: ponelat
234 | uuid:
235 | type: string
236 | example: f7f680a8-d111-421f-b6b3-493ebf905078
237 |
238 |
239 | /tokens:
240 | post:
241 | tags:
242 | - Users
243 | description: Create a new token
244 | requestBody:
245 | content:
246 | application/json:
247 | schema:
248 | type: object
249 | properties:
250 | username:
251 | type: string
252 | example: ponelat
253 | password:
254 | type: string
255 | format: password
256 |
257 | responses:
258 | '201':
259 | description: Create a new token for gaining authenticated access to resources
260 | content:
261 | application/json:
262 | schema:
263 | type: object
264 | properties:
265 | token:
266 | type: string
267 |
268 |
269 | components:
270 | securitySchemes:
271 | MyUserToken:
272 | name: Authorization
273 | type: apiKey
274 | in: header
275 |
--------------------------------------------------------------------------------
/ch08/site/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | FarmStall API v1
9 |
10 |
11 |
12 |
13 |
14 |
15 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/ch08/site/openapi.yml:
--------------------------------------------------------------------------------
1 | openapi: 3.0.3
2 | info:
3 | version: v1
4 | title: FarmStall API
5 | description: |-
6 |
7 | An API for writing reviews about your favourite (or worst) farm stalls.
8 |
9 | 
10 |
11 | ---
12 |
13 | # Auth
14 |
15 | To create **Reviews** without being _anonymous_. You need to add a **MyUserToken** to the `Authorization` header.
16 |
17 | To get a **MyUserToken**:
18 | 1. Create a **User** with [POST /users](#Users/post_users)
19 | 1. Get a **MyUserToken** by calling [POST /tokens](#Users/post_tokens) with your **User** credentials.
20 |
21 | # Reviews
22 | Reviews are the heart of this API.
23 | Registered **Users** and anonymous users can both write reviews based on their experience at farm stalls.
24 |
25 | Each review comes with a rating of between one and five stars inclusive.
26 |
27 | - One star being the worst experience
28 | - Five stars being the best
29 |
30 |
31 | ### Example Reviews
32 |
33 | "A wonderful time!" — Bob McNally
34 |
35 | 
36 |
37 | "An awful place" — _Anonymous_
38 |
39 | 
40 |
41 | "A totally average place." — Jane Fair
42 |
43 | 
44 |
45 | contact:
46 | name: Josh Ponelat
47 | email: jponelat+daso@gmail.com
48 | url: https://farmstall.designapis.com
49 |
50 | license:
51 | url: https://www.apache.org/licenses/LICENSE-2.0
52 | name: Apache 2.0
53 |
54 | externalDocs:
55 | url: https://farmstall.designapis.com
56 | description: Hosted docs
57 |
58 | tags:
59 | - name: Reviews
60 | description: Reviews of your favourite/worst farm stalls
61 |
62 | - name: Users
63 | description: Users and authentication
64 |
65 | servers:
66 | - url: 'https://farmstall.designapis.com/v1'
67 |
68 | paths:
69 | /reviews:
70 | get:
71 | tags:
72 | - Reviews
73 | description: Get a list of reviews
74 | parameters:
75 | - name: maxRating
76 | in: query
77 | schema:
78 | type: number
79 | responses:
80 | '200':
81 | description: A bunch of reviews
82 | content:
83 | application/json:
84 | schema:
85 | type: array
86 | items:
87 | type: object
88 | properties:
89 | rating:
90 | type: integer
91 | minimum: 1
92 | maximum: 5
93 | message:
94 | type: string
95 | example: An awesome time for the whole family.
96 | uuid:
97 | type: string
98 | pattern: '^[0-9a-fA-F\-]{36}$'
99 | example: 3b5b1707-b82c-4b1d-9078-157053902525
100 | userId:
101 | type: string
102 | pattern: '^[0-9a-fA-F\-]{36}$'
103 | nullable: true
104 | example: 3b5b1707-b82c-4b1d-9078-157053902525
105 |
106 | post:
107 | tags:
108 | - Reviews
109 | description: Create a new Review
110 | security:
111 | - MyUserToken: []
112 | requestBody:
113 | description: A new Review
114 | content:
115 | application/json:
116 | schema:
117 | type: object
118 | properties:
119 | message:
120 | type: string
121 | example: An awesome time for the whole family.
122 | rating:
123 | type: integer
124 | minimum: 1
125 | maximum: 5
126 | example: 5
127 | responses:
128 | '201':
129 | description: Successfully created a new Review
130 | content:
131 | application/json:
132 | schema:
133 | type: object
134 | properties:
135 | message:
136 | type: string
137 | example: An awesome time for the whole family.
138 | rating:
139 | type: integer
140 | minimum: 1
141 | maximum: 5
142 | example: 5
143 | userId:
144 | type: string
145 | nullable: true
146 | pattern: '^[0-9a-fA-F\-]{36}$'
147 | example: 3b5b1707-b82c-4b1d-9078-157053902525
148 | uuid:
149 | type: string
150 | pattern: '^[0-9a-fA-F\-]{36}$'
151 | example: 3b5b1707-b82c-4b1d-9078-157053902525
152 |
153 |
154 | /reviews/{reviewId}:
155 | get:
156 | tags:
157 | - Reviews
158 | description: Get a single review
159 | parameters:
160 | - name: reviewId
161 | in: path
162 | required: true
163 | schema:
164 | type: string
165 | description: The review's ID
166 | example: 3b5b1707-b82c-4b1d-9078-157053902525
167 | minLength: 36
168 | maxLength: 36
169 | pattern: '[a-zA-Z0-9-]+'
170 | responses:
171 | '200':
172 | description: A single review
173 | content:
174 | application/json:
175 | schema:
176 | type: object
177 | properties:
178 | message:
179 | type: string
180 | example: An awesome time for the whole family.
181 | rating:
182 | type: integer
183 | minimum: 1
184 | maximum: 5
185 | example: 5
186 | userId:
187 | minLength: 36
188 | maxLength: 36
189 | pattern: '^[a-zA-Z0-9-]+$'
190 | nullable: true
191 | example: 3b5b1707-b82c-4b1d-9078-157053902525
192 | uuid:
193 | minLength: 36
194 | maxLength: 36
195 | pattern: '^[a-zA-Z0-9-]+$'
196 | example: 3b5b1707-b82c-4b1d-9078-157053902525
197 | '404':
198 | description: Review not found
199 |
200 |
201 |
202 | /users:
203 | post:
204 | tags:
205 | - Users
206 | description: Create a new user
207 | requestBody:
208 | description: User details
209 | content:
210 | application/json:
211 | schema:
212 | type: object
213 | properties:
214 | username:
215 | type: string
216 | example: ponelat
217 | password:
218 | type: string
219 | format: password
220 | fullName:
221 | type: string
222 | example: Josh Ponelat
223 | responses:
224 | '201':
225 | description: Successfully created a new user
226 | content:
227 | application/json:
228 | schema:
229 | type: object
230 | properties:
231 | username:
232 | type: string
233 | example: ponelat
234 | uuid:
235 | type: string
236 | example: f7f680a8-d111-421f-b6b3-493ebf905078
237 |
238 |
239 | /tokens:
240 | post:
241 | tags:
242 | - Users
243 | description: Create a new token
244 | requestBody:
245 | content:
246 | application/json:
247 | schema:
248 | type: object
249 | properties:
250 | username:
251 | type: string
252 | example: ponelat
253 | password:
254 | type: string
255 | format: password
256 |
257 | responses:
258 | '201':
259 | description: Create a new token for gaining authenticated access to resources
260 | content:
261 | application/json:
262 | schema:
263 | type: object
264 | properties:
265 | token:
266 | type: string
267 |
268 |
269 | components:
270 | securitySchemes:
271 | MyUserToken:
272 | name: Authorization
273 | type: apiKey
274 | in: header
275 |
--------------------------------------------------------------------------------
/ch08/site/site.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/designapis/openapi/4b0cc3d98e9682a81bc00163f3acedd7b3cfdd3c/ch08/site/site.zip
--------------------------------------------------------------------------------
/ch10/01.yml:
--------------------------------------------------------------------------------
1 | openapi: 3.0.3
2 | info:
3 | title: PetSitter API
4 | version: "0.1"
5 | paths: {}
6 | components:
7 | schemas:
8 | User:
9 | type: object
10 | properties:
11 | id:
12 | type: integer
13 | email:
14 | type: string
15 | password:
16 | type: string
17 | full_name:
18 | type: string
19 | roles:
20 | type: array
21 | items:
22 | type: string
23 |
--------------------------------------------------------------------------------
/ch10/README.md:
--------------------------------------------------------------------------------
1 | # Chapter 10: Creating an API design using OpenAPI
2 |
3 | Supporting files for [chapter 10 of Designing APIs with Swagger and OpenAPI](https://livebook.manning.com/book/designing-apis-with-swagger-and-openapi/chapter-10).
4 |
--------------------------------------------------------------------------------
/ch10/openapi.yml:
--------------------------------------------------------------------------------
1 | openapi: 3.0.3
2 | info:
3 | title: PetSitter API
4 | version: "0.1"
5 | paths:
6 | /users:
7 | post:
8 | summary: Register User
9 | responses:
10 | '201':
11 | description: Created
12 | headers:
13 | Location:
14 | schema:
15 | type: string
16 | requestBody:
17 | content:
18 | application/json:
19 | schema:
20 | $ref: '#/components/schemas/User'
21 | /users/{id}:
22 | parameters:
23 | - schema:
24 | type: integer
25 | name: id
26 | in: path
27 | required: true
28 | get:
29 | summary: View User
30 | responses:
31 | '200':
32 | description: OK
33 | content:
34 | application/json:
35 | schema:
36 | $ref: '#/components/schemas/User'
37 | put:
38 | summary: Modify User
39 | responses:
40 | '200':
41 | description: OK
42 | content:
43 | application/json:
44 | schema:
45 | $ref: '#/components/schemas/User'
46 | requestBody:
47 | content:
48 | application/json:
49 | schema:
50 | $ref: '#/components/schemas/User'
51 | delete:
52 | summary: Delete User
53 | responses:
54 | '204':
55 | description: No Content
56 | /jobs:
57 | post:
58 | summary: Create Job
59 | responses:
60 | '201':
61 | description: Created
62 | headers:
63 | Location:
64 | schema:
65 | type: string
66 | requestBody:
67 | content:
68 | application/json:
69 | schema:
70 | $ref: '#/components/schemas/Job'
71 | get:
72 | summary: List All Jobs
73 | responses:
74 | '200':
75 | description: OK
76 | content:
77 | application/json:
78 | schema:
79 | type: object
80 | properties:
81 | items:
82 | type: array
83 | items:
84 | $ref: '#/components/schemas/Job'
85 | /jobs/{id}:
86 | parameters:
87 | - schema:
88 | type: integer
89 | name: id
90 | in: path
91 | required: true
92 | get:
93 | summary: View Job
94 | responses:
95 | '200':
96 | description: OK
97 | content:
98 | application/json:
99 | schema:
100 | $ref: '#/components/schemas/Job'
101 | put:
102 | summary: Modify Job
103 | responses:
104 | '200':
105 | description: OK
106 | content:
107 | application/json:
108 | schema:
109 | $ref: '#/components/schemas/Job'
110 | requestBody:
111 | content:
112 | application/json:
113 | schema:
114 | $ref: '#/components/schemas/Job'
115 | /jobs/{id}/job-applications:
116 | parameters:
117 | - schema:
118 | type: integer
119 | name: id
120 | in: path
121 | required: true
122 | get:
123 | summary: List Applications For Job
124 | responses:
125 | '200':
126 | description: OK
127 | content:
128 | application/json:
129 | schema:
130 | type: object
131 | properties:
132 | items:
133 | type: array
134 | items:
135 | $ref: '#/components/schemas/JobApplication'
136 | post:
137 | summary: Create Job Application
138 | responses:
139 | '201':
140 | description: Created
141 | headers:
142 | Location:
143 | schema:
144 | type: string
145 | requestBody:
146 | content:
147 | application/json:
148 | schema:
149 | $ref: '#/components/schemas/JobApplication'
150 | /users/{id}/jobs:
151 | parameters:
152 | - schema:
153 | type: integer
154 | name: id
155 | in: path
156 | required: true
157 | get:
158 | summary: List Jobs For User
159 | responses:
160 | '200':
161 | description: OK
162 | content:
163 | application/json:
164 | schema:
165 | type: object
166 | properties:
167 | items:
168 | type: array
169 | items:
170 | $ref: '#/components/schemas/Job'
171 | /job-applications/{id}:
172 | parameters:
173 | - schema:
174 | type: integer
175 | name: id
176 | in: path
177 | required: true
178 | put:
179 | summary: Modify Job Application
180 | requestBody:
181 | description: Update the application details
182 | content:
183 | application/json:
184 | schema:
185 | $ref: '#/components/schemas/JobApplication'
186 |
187 | responses:
188 | '200':
189 | description: OK
190 | content:
191 | application/json:
192 | schema:
193 | $ref: '#/components/schemas/JobApplication'
194 | components:
195 | schemas:
196 | User:
197 | type: object
198 | properties:
199 | id:
200 | type: integer
201 | email:
202 | type: string
203 | password:
204 | type: string
205 | full_name:
206 | type: string
207 | roles:
208 | type: array
209 | items:
210 | type: string
211 | Job:
212 | type: object
213 | properties:
214 | id:
215 | type: integer
216 | creator_user_id:
217 | type: integer
218 | start_time:
219 | type: string
220 | end_time:
221 | type: string
222 | activity:
223 | type: string
224 | dog:
225 | $ref: '#/components/schemas/Dog'
226 | Dog:
227 | type: object
228 | properties:
229 | name:
230 | type: string
231 | age:
232 | type: integer
233 | breed:
234 | type: string
235 | size:
236 | type: string
237 | JobApplication:
238 | type: object
239 | properties:
240 | id:
241 | type: integer
242 | status:
243 | type: string
244 | user_id:
245 | type: integer
246 | job_id:
247 | type: integer
248 |
--------------------------------------------------------------------------------
/ch11/README.md:
--------------------------------------------------------------------------------
1 | # Chapter 11: Building a change workflow around API Design First
2 |
3 | Supporting files for [chapter 11 of Designing APIs with Swagger and OpenAPI](https://livebook.manning.com/book/designing-apis-with-swagger-and-openapi/chapter-11).
4 |
--------------------------------------------------------------------------------
/ch11/openapi.yml:
--------------------------------------------------------------------------------
1 | openapi: 3.0.3
2 | info:
3 | title: PetSitter API
4 | version: "0.1"
5 | paths:
6 | /users:
7 | post:
8 | summary: Register User
9 | responses:
10 | '201':
11 | description: Created
12 | headers:
13 | Location:
14 | schema:
15 | type: string
16 | requestBody:
17 | content:
18 | application/json:
19 | schema:
20 | $ref: '#/components/schemas/User'
21 | /users/{id}:
22 | parameters:
23 | - schema:
24 | type: integer
25 | name: id
26 | in: path
27 | required: true
28 | get:
29 | summary: View User
30 | responses:
31 | '200':
32 | description: OK
33 | content:
34 | application/json:
35 | schema:
36 | $ref: '#/components/schemas/User'
37 | put:
38 | summary: Modify User
39 | responses:
40 | '200':
41 | description: OK
42 | content:
43 | application/json:
44 | schema:
45 | $ref: '#/components/schemas/User'
46 | requestBody:
47 | content:
48 | application/json:
49 | schema:
50 | $ref: '#/components/schemas/User'
51 | delete:
52 | summary: Delete User
53 | responses:
54 | '204':
55 | description: No Content
56 | /jobs:
57 | post:
58 | summary: Create Job
59 | responses:
60 | '201':
61 | description: Created
62 | headers:
63 | Location:
64 | schema:
65 | type: string
66 | requestBody:
67 | content:
68 | application/json:
69 | schema:
70 | $ref: '#/components/schemas/Job'
71 | get:
72 | summary: List All Jobs
73 | responses:
74 | '200':
75 | description: OK
76 | content:
77 | application/json:
78 | schema:
79 | type: object
80 | properties:
81 | items:
82 | type: array
83 | items:
84 | $ref: '#/components/schemas/Job'
85 | /jobs/{id}:
86 | parameters:
87 | - schema:
88 | type: integer
89 | name: id
90 | in: path
91 | required: true
92 | get:
93 | summary: View Job
94 | responses:
95 | '200':
96 | description: OK
97 | content:
98 | application/json:
99 | schema:
100 | $ref: '#/components/schemas/Job'
101 | put:
102 | summary: Modify Job
103 | responses:
104 | '200':
105 | description: OK
106 | content:
107 | application/json:
108 | schema:
109 | $ref: '#/components/schemas/Job'
110 | requestBody:
111 | content:
112 | application/json:
113 | schema:
114 | $ref: '#/components/schemas/Job'
115 | delete:
116 | summary: Delete Job
117 | responses:
118 | '204':
119 | description: No Content
120 | /jobs/{id}/job-applications:
121 | parameters:
122 | - schema:
123 | type: integer
124 | name: id
125 | in: path
126 | required: true
127 | get:
128 | summary: List Applications For Job
129 | responses:
130 | '200':
131 | description: OK
132 | content:
133 | application/json:
134 | schema:
135 | type: object
136 | properties:
137 | items:
138 | type: array
139 | items:
140 | $ref: '#/components/schemas/JobApplication'
141 | post:
142 | summary: Create Job Application
143 | responses:
144 | '201':
145 | description: Created
146 | headers:
147 | Location:
148 | schema:
149 | type: string
150 | requestBody:
151 | content:
152 | application/json:
153 | schema:
154 | $ref: '#/components/schemas/JobApplication'
155 | /users/{id}/jobs:
156 | parameters:
157 | - schema:
158 | type: integer
159 | name: id
160 | in: path
161 | required: true
162 | get:
163 | summary: List Jobs For User
164 | responses:
165 | '200':
166 | description: OK
167 | content:
168 | application/json:
169 | schema:
170 | type: object
171 | properties:
172 | items:
173 | type: array
174 | items:
175 | $ref: '#/components/schemas/Job'
176 | /job-applications/{id}:
177 | parameters:
178 | - schema:
179 | type: integer
180 | name: id
181 | in: path
182 | required: true
183 | put:
184 | summary: Modify Job Application
185 | requestBody:
186 | description: Update the application details
187 | content:
188 | application/json:
189 | schema:
190 | $ref: '#/components/schemas/JobApplication'
191 |
192 | responses:
193 | '200':
194 | description: OK
195 | content:
196 | application/json:
197 | schema:
198 | $ref: '#/components/schemas/JobApplication'
199 | components:
200 | schemas:
201 | User:
202 | type: object
203 | properties:
204 | id:
205 | type: integer
206 | email:
207 | type: string
208 | password:
209 | type: string
210 | full_name:
211 | type: string
212 | roles:
213 | type: array
214 | items:
215 | type: string
216 | Job:
217 | type: object
218 | properties:
219 | id:
220 | type: integer
221 | creator_user_id:
222 | type: integer
223 | start_time:
224 | type: string
225 | end_time:
226 | type: string
227 | activity:
228 | type: string
229 | dog:
230 | $ref: '#/components/schemas/Dog'
231 | Dog:
232 | type: object
233 | properties:
234 | name:
235 | type: string
236 | age:
237 | type: integer
238 | breed:
239 | type: string
240 | size:
241 | type: string
242 | JobApplication:
243 | type: object
244 | properties:
245 | id:
246 | type: integer
247 | status:
248 | type: string
249 | user_id:
250 | type: integer
251 | job_id:
252 | type: integer
253 |
--------------------------------------------------------------------------------
/ch12/01.yml:
--------------------------------------------------------------------------------
1 | openapi: 3.0.3
2 | info:
3 | title: PetSitter API
4 | version: "0.1"
5 | paths:
6 | /users:
7 | post:
8 | summary: Register User
9 | responses:
10 | '201':
11 | description: Created
12 | headers:
13 | Location:
14 | schema:
15 | type: string
16 | requestBody:
17 | content:
18 | application/json:
19 | schema:
20 | $ref: '#/components/schemas/User'
21 | /users/{id}:
22 | parameters:
23 | - schema:
24 | type: integer
25 | name: id
26 | in: path
27 | required: true
28 | get:
29 | summary: View User
30 | responses:
31 | '200':
32 | description: OK
33 | content:
34 | application/json:
35 | schema:
36 | $ref: '#/components/schemas/User'
37 | put:
38 | summary: Modify User
39 | responses:
40 | '200':
41 | description: OK
42 | content:
43 | application/json:
44 | schema:
45 | $ref: '#/components/schemas/User'
46 | requestBody:
47 | content:
48 | application/json:
49 | schema:
50 | $ref: '#/components/schemas/User'
51 | delete:
52 | summary: Delete User
53 | responses:
54 | '204':
55 | description: No Content
56 | /jobs:
57 | post:
58 | summary: Create Job
59 | responses:
60 | '201':
61 | description: Created
62 | headers:
63 | Location:
64 | schema:
65 | type: string
66 | requestBody:
67 | content:
68 | application/json:
69 | schema:
70 | $ref: '#/components/schemas/Job'
71 | get:
72 | summary: List All Jobs
73 | responses:
74 | '200':
75 | description: OK
76 | content:
77 | application/json:
78 | schema:
79 | type: object
80 | properties:
81 | items:
82 | type: array
83 | items:
84 | $ref: '#/components/schemas/Job'
85 | examples:
86 | with-some-data:
87 | summary: With some data
88 | value:
89 | items:
90 | - id: 123
91 | creator_user_id: 345
92 | start_time: 2020-06-01T00:00:00Z
93 | end_time: 2020-06-02T00:00:00Z
94 | dog:
95 | name: Fido
96 | age: 3
97 | breed: Doberman
98 | size: medium
99 | activity: walk
100 | - id: 234
101 | creator_user_id: 345
102 | start_time: 2020-06-01T00:00:00Z
103 | end_time: 2020-06-03T00:00:00Z
104 | dog:
105 | name: Rex
106 | age: 2
107 | breed: Rottweiler
108 | size: large
109 | activity: sit
110 | - id: 234
111 | creator_user_id: 345
112 | start_time: 2020-06-01T00:00:00Z
113 | end_time: 2020-06-02T00:00:00Z
114 | dog:
115 | name: Blossom
116 | age: 2
117 | breed: Rottweiler
118 | size: large
119 | activity: walk
120 |
121 | /jobs/{id}:
122 | parameters:
123 | - schema:
124 | type: integer
125 | name: id
126 | in: path
127 | required: true
128 | get:
129 | summary: View Job
130 | responses:
131 | '200':
132 | description: OK
133 | content:
134 | application/json:
135 | schema:
136 | $ref: '#/components/schemas/Job'
137 | put:
138 | summary: Modify Job
139 | responses:
140 | '200':
141 | description: OK
142 | content:
143 | application/json:
144 | schema:
145 | $ref: '#/components/schemas/Job'
146 | requestBody:
147 | content:
148 | application/json:
149 | schema:
150 | $ref: '#/components/schemas/Job'
151 | delete:
152 | summary: Delete Job
153 | responses:
154 | '204':
155 | description: No Content
156 | /jobs/{id}/job-applications:
157 | parameters:
158 | - schema:
159 | type: integer
160 | name: id
161 | in: path
162 | required: true
163 | get:
164 | summary: List Applications For Job
165 | responses:
166 | '200':
167 | description: OK
168 | content:
169 | application/json:
170 | schema:
171 | type: object
172 | properties:
173 | items:
174 | type: array
175 | items:
176 | $ref: '#/components/schemas/JobApplication'
177 | post:
178 | summary: Create Job Application
179 | responses:
180 | '201':
181 | description: Created
182 | headers:
183 | Location:
184 | schema:
185 | type: string
186 | requestBody:
187 | content:
188 | application/json:
189 | schema:
190 | $ref: '#/components/schemas/JobApplication'
191 | /users/{id}/jobs:
192 | parameters:
193 | - schema:
194 | type: integer
195 | name: id
196 | in: path
197 | required: true
198 | get:
199 | summary: List Jobs For User
200 | responses:
201 | '200':
202 | description: OK
203 | content:
204 | application/json:
205 | schema:
206 | type: object
207 | properties:
208 | items:
209 | type: array
210 | items:
211 | $ref: '#/components/schemas/Job'
212 | /job-applications/{id}:
213 | parameters:
214 | - schema:
215 | type: integer
216 | name: id
217 | in: path
218 | required: true
219 | put:
220 | summary: Modify Job Application
221 | requestBody:
222 | description: Update the application details
223 | content:
224 | application/json:
225 | schema:
226 | $ref: '#/components/schemas/JobApplication'
227 |
228 | responses:
229 | '200':
230 | description: OK
231 | content:
232 | application/json:
233 | schema:
234 | $ref: '#/components/schemas/JobApplication'
235 | components:
236 | schemas:
237 | User:
238 | type: object
239 | properties:
240 | id:
241 | type: integer
242 | email:
243 | type: string
244 | password:
245 | type: string
246 | full_name:
247 | type: string
248 | roles:
249 | type: array
250 | items:
251 | type: string
252 | Job:
253 | type: object
254 | properties:
255 | id:
256 | type: integer
257 | creator_user_id:
258 | type: integer
259 | start_time:
260 | type: string
261 | end_time:
262 | type: string
263 | activity:
264 | type: string
265 | dog:
266 | $ref: '#/components/schemas/Dog'
267 | Dog:
268 | type: object
269 | properties:
270 | name:
271 | type: string
272 | age:
273 | type: integer
274 | breed:
275 | type: string
276 | size:
277 | type: string
278 | JobApplication:
279 | type: object
280 | properties:
281 | id:
282 | type: integer
283 | status:
284 | type: string
285 | user_id:
286 | type: integer
287 | job_id:
288 | type: integer
289 |
--------------------------------------------------------------------------------
/ch12/02.yml:
--------------------------------------------------------------------------------
1 | items:
2 | - id: 0
3 | user_id: 358
4 | job_id: 4012
5 | status: COMPLETE
6 | - id: 1
7 | user_id: 3089
8 | job_id: 3902
9 | status: PENDING
10 | - id: 2
11 | user_id: 4040
12 | job_id: 5269
13 | status: PENDING
14 | - id: 3
15 | user_id: 5636
16 | job_id: 8420
17 | status: PENDING
18 | - id: 4
19 | user_id: 9540
20 | job_id: 9505
21 | status: COMPLETE
22 | - id: 5
23 | user_id: 9873
24 | job_id: 3215
25 | status: PENDING
26 | - id: 6
27 | user_id: 6032
28 | job_id: 7365
29 | status: COMPLETE
30 | - id: 7
31 | user_id: 5999
32 | job_id: 1159
33 | status: COMPLETE
34 | - id: 8
35 | user_id: 2897
36 | job_id: 7982
37 | status: COMPLETE
38 | - id: 9
39 | user_id: 227
40 | job_id: 9245
41 | status: CANCELLED
42 | - id: 10
43 | user_id: 741
44 | job_id: 2752
45 | status: CANCELLED
46 | - id: 11
47 | user_id: 9059
48 | job_id: 338
49 | status: PENDING
50 | - id: 12
51 | user_id: 1379
52 | job_id: 4531
53 | status: COMPLETE
54 | - id: 13
55 | user_id: 2031
56 | job_id: 9375
57 | status: COMPLETE
58 | - id: 14
59 | user_id: 3643
60 | job_id: 5175
61 | status: CANCELLED
62 | - id: 15
63 | user_id: 5470
64 | job_id: 831
65 | status: CANCELLED
66 | - id: 16
67 | user_id: 3265
68 | job_id: 5597
69 | status: PENDING
70 | - id: 17
71 | user_id: 2815
72 | job_id: 7719
73 | status: PENDING
74 | - id: 18
75 | user_id: 8306
76 | job_id: 679
77 | status: PENDING
78 | - id: 19
79 | user_id: 9742
80 | job_id: 8239
81 | status: PENDING
82 | - id: 20
83 | user_id: 4851
84 | job_id: 940
85 | status: PENDING
86 | - id: 21
87 | user_id: 6700
88 | job_id: 4040
89 | status: PENDING
90 | - id: 22
91 | user_id: 7067
92 | job_id: 6016
93 | status: PENDING
94 | - id: 23
95 | user_id: 3265
96 | job_id: 1822
97 | status: PENDING
98 | - id: 24
99 | user_id: 8333
100 | job_id: 9988
101 | status: PENDING
102 | - id: 25
103 | user_id: 7543
104 | job_id: 9307
105 | status: PENDING
106 | - id: 26
107 | user_id: 5429
108 | job_id: 7511
109 | status: COMPLETE
110 | - id: 27
111 | user_id: 3576
112 | job_id: 1710
113 | status: PENDING
114 | - id: 28
115 | user_id: 590
116 | job_id: 2634
117 | status: COMPLETE
118 | - id: 29
119 | user_id: 2327
120 | job_id: 7205
121 | status: CANCELLED
122 | - id: 30
123 | user_id: 2193
124 | job_id: 7421
125 | status: COMPLETE
126 | - id: 31
127 | user_id: 5014
128 | job_id: 6781
129 | status: CANCELLED
130 | - id: 32
131 | user_id: 9216
132 | job_id: 8047
133 | status: COMPLETE
134 | - id: 33
135 | user_id: 3369
136 | job_id: 7438
137 | status: CANCELLED
138 | - id: 34
139 | user_id: 9825
140 | job_id: 6758
141 | status: PENDING
142 | - id: 35
143 | user_id: 3250
144 | job_id: 7760
145 | status: COMPLETE
146 | - id: 36
147 | user_id: 1552
148 | job_id: 4030
149 | status: COMPLETE
150 | - id: 37
151 | user_id: 9221
152 | job_id: 3971
153 | status: CANCELLED
154 | - id: 38
155 | user_id: 6816
156 | job_id: 7878
157 | status: PENDING
158 | - id: 39
159 | user_id: 6109
160 | job_id: 4060
161 | status: CANCELLED
162 |
--------------------------------------------------------------------------------
/ch12/03.yml:
--------------------------------------------------------------------------------
1 | openapi: 3.0.3
2 | info:
3 | title: Tiny API
4 | version: "1.0.0"
5 | paths:
6 | /foo:
7 | get:
8 | description: Simple get
9 | responses:
10 | '200':
11 | description: Get Foo
12 | content:
13 | application/json:
14 | examples:
15 | one:
16 | value:
17 | foo: 1
18 | two:
19 | value:
20 | foo: 2
21 | schema:
22 | type: object
23 | '404':
24 | description: No Foo
25 | content:
26 | application/json:
27 | examples:
28 | error:
29 | value:
30 | msg: I am an error example
31 |
--------------------------------------------------------------------------------
/ch12/README.md:
--------------------------------------------------------------------------------
1 | # Chapter 12: Implementing frontend code and reacting to changes
2 |
3 | The file [openapi.yaml](openapi.yaml) contains the OpenAPI file for the PetSitter project after the updates made in [chapter 12](https://livebook.manning.com/book/designing-apis-with-swagger-and-openapi/chapter-12).
--------------------------------------------------------------------------------
/ch12/openapi.yml:
--------------------------------------------------------------------------------
1 | openapi: 3.0.3
2 | info:
3 | title: PetSitter API
4 | version: "0.1"
5 | paths:
6 | /users:
7 | post:
8 | summary: Register User
9 | responses:
10 | '201':
11 | description: Created
12 | headers:
13 | Location:
14 | schema:
15 | type: string
16 | requestBody:
17 | content:
18 | application/json:
19 | schema:
20 | $ref: '#/components/schemas/User'
21 | /users/{id}:
22 | parameters:
23 | - schema:
24 | type: integer
25 | name: id
26 | in: path
27 | required: true
28 | get:
29 | summary: View User
30 | responses:
31 | '200':
32 | description: OK
33 | content:
34 | application/json:
35 | schema:
36 | $ref: '#/components/schemas/User'
37 | put:
38 | summary: Modify User
39 | responses:
40 | '200':
41 | description: OK
42 | content:
43 | application/json:
44 | schema:
45 | $ref: '#/components/schemas/User'
46 | requestBody:
47 | content:
48 | application/json:
49 | schema:
50 | $ref: '#/components/schemas/User'
51 | delete:
52 | summary: Delete User
53 | responses:
54 | '204':
55 | description: No Content
56 | /jobs:
57 | post:
58 | summary: Create Job
59 | responses:
60 | '201':
61 | description: Created
62 | headers:
63 | Location:
64 | schema:
65 | type: string
66 | requestBody:
67 | content:
68 | application/json:
69 | schema:
70 | $ref: '#/components/schemas/Job'
71 | get:
72 | summary: List All Jobs
73 | responses:
74 | '200':
75 | description: OK
76 | content:
77 | application/json:
78 | schema:
79 | type: object
80 | properties:
81 | items:
82 | type: array
83 | items:
84 | $ref: '#/components/schemas/Job'
85 | examples:
86 | with-some-data:
87 | summary: With some data
88 | value:
89 | items:
90 | - id: 123
91 | creator_user_id: 345
92 | start_time: 2020-06-01T00:00:00Z
93 | end_time: 2020-06-02T00:00:00Z
94 | dog:
95 | name: Fido
96 | age: 3
97 | breed: Doberman
98 | size: medium
99 | activity: walk
100 | - id: 234
101 | creator_user_id: 345
102 | start_time: 2020-06-01T00:00:00Z
103 | end_time: 2020-06-03T00:00:00Z
104 | dog:
105 | name: Rex
106 | age: 2
107 | breed: Rottweiler
108 | size: large
109 | activity: sit
110 | - id: 234
111 | creator_user_id: 345
112 | start_time: 2020-06-01T00:00:00Z
113 | end_time: 2020-06-02T00:00:00Z
114 | dog:
115 | name: Blossom
116 | age: 2
117 | breed: Rottweiler
118 | size: large
119 | activity: walk
120 | /jobs/{id}:
121 | parameters:
122 | - schema:
123 | type: integer
124 | name: id
125 | in: path
126 | required: true
127 | get:
128 | summary: View Job
129 | responses:
130 | '200':
131 | description: OK
132 | content:
133 | application/json:
134 | schema:
135 | $ref: '#/components/schemas/Job'
136 | put:
137 | summary: Modify Job
138 | responses:
139 | '200':
140 | description: OK
141 | content:
142 | application/json:
143 | schema:
144 | $ref: '#/components/schemas/Job'
145 | requestBody:
146 | content:
147 | application/json:
148 | schema:
149 | $ref: '#/components/schemas/Job'
150 | delete:
151 | summary: Delete Job
152 | responses:
153 | '204':
154 | description: No Content
155 | /jobs/{id}/job-applications:
156 | parameters:
157 | - schema:
158 | type: integer
159 | name: id
160 | in: path
161 | required: true
162 | get:
163 | summary: List Applications For Job
164 | responses:
165 | '200':
166 | description: OK
167 | content:
168 | application/json:
169 | schema:
170 | type: object
171 | properties:
172 | items:
173 | type: array
174 | items:
175 | $ref: '#/components/schemas/JobApplication'
176 | post:
177 | summary: Create Job Application
178 | responses:
179 | '201':
180 | description: Created
181 | headers:
182 | Location:
183 | schema:
184 | type: string
185 | requestBody:
186 | content:
187 | application/json:
188 | schema:
189 | $ref: '#/components/schemas/JobApplication'
190 | /users/{id}/jobs:
191 | parameters:
192 | - schema:
193 | type: integer
194 | name: id
195 | in: path
196 | required: true
197 | get:
198 | summary: List Jobs For User
199 | responses:
200 | '200':
201 | description: OK
202 | content:
203 | application/json:
204 | schema:
205 | type: object
206 | properties:
207 | items:
208 | type: array
209 | items:
210 | $ref: '#/components/schemas/Job'
211 | /users/{id}/job-applications:
212 | parameters:
213 | - name: id
214 | in: path
215 | required: true
216 | schema:
217 | type: integer
218 | get:
219 | summary: List Applications For User
220 | responses:
221 | '200':
222 | description: OK
223 | content:
224 | application/json:
225 | examples:
226 | empty:
227 | summary: Zero Job Applications
228 | value:
229 | items: []
230 | two-items:
231 | summary: Two Job Applications
232 | value:
233 | items:
234 | - id: 123
235 | user_id: 123
236 | job_id: 123
237 | status: PENDING
238 | - id: 123
239 | user_id: 123
240 | job_id: 123
241 | status: COMPLETE
242 | many:
243 | summary: Many Job Applications
244 | value:
245 | items:
246 | - id: 0
247 | user_id: 358
248 | job_id: 4012
249 | status: COMPLETE
250 | - id: 1
251 | user_id: 3089
252 | job_id: 3902
253 | status: PENDING
254 | - id: 2
255 | user_id: 4040
256 | job_id: 5269
257 | status: PENDING
258 | - id: 3
259 | user_id: 5636
260 | job_id: 8420
261 | status: PENDING
262 | - id: 4
263 | user_id: 9540
264 | job_id: 9505
265 | status: COMPLETE
266 | - id: 5
267 | user_id: 9873
268 | job_id: 3215
269 | status: PENDING
270 | - id: 6
271 | user_id: 6032
272 | job_id: 7365
273 | status: COMPLETE
274 | - id: 7
275 | user_id: 5999
276 | job_id: 1159
277 | status: COMPLETE
278 | - id: 8
279 | user_id: 2897
280 | job_id: 7982
281 | status: COMPLETE
282 | - id: 9
283 | user_id: 227
284 | job_id: 9245
285 | status: CANCELLED
286 | - id: 10
287 | user_id: 741
288 | job_id: 2752
289 | status: CANCELLED
290 | - id: 11
291 | user_id: 9059
292 | job_id: 338
293 | status: PENDING
294 | - id: 12
295 | user_id: 1379
296 | job_id: 4531
297 | status: COMPLETE
298 | - id: 13
299 | user_id: 2031
300 | job_id: 9375
301 | status: COMPLETE
302 | - id: 14
303 | user_id: 3643
304 | job_id: 5175
305 | status: CANCELLED
306 | - id: 15
307 | user_id: 5470
308 | job_id: 831
309 | status: CANCELLED
310 | - id: 16
311 | user_id: 3265
312 | job_id: 5597
313 | status: PENDING
314 | - id: 17
315 | user_id: 2815
316 | job_id: 7719
317 | status: PENDING
318 | - id: 18
319 | user_id: 8306
320 | job_id: 679
321 | status: PENDING
322 | - id: 19
323 | user_id: 9742
324 | job_id: 8239
325 | status: PENDING
326 | - id: 20
327 | user_id: 4851
328 | job_id: 940
329 | status: PENDING
330 | - id: 21
331 | user_id: 6700
332 | job_id: 4040
333 | status: PENDING
334 | - id: 22
335 | user_id: 7067
336 | job_id: 6016
337 | status: PENDING
338 | - id: 23
339 | user_id: 3265
340 | job_id: 1822
341 | status: PENDING
342 | - id: 24
343 | user_id: 8333
344 | job_id: 9988
345 | status: PENDING
346 | - id: 25
347 | user_id: 7543
348 | job_id: 9307
349 | status: PENDING
350 | - id: 26
351 | user_id: 5429
352 | job_id: 7511
353 | status: COMPLETE
354 | - id: 27
355 | user_id: 3576
356 | job_id: 1710
357 | status: PENDING
358 | - id: 28
359 | user_id: 590
360 | job_id: 2634
361 | status: COMPLETE
362 | - id: 29
363 | user_id: 2327
364 | job_id: 7205
365 | status: CANCELLED
366 | - id: 30
367 | user_id: 2193
368 | job_id: 7421
369 | status: COMPLETE
370 | - id: 31
371 | user_id: 5014
372 | job_id: 6781
373 | status: CANCELLED
374 | - id: 32
375 | user_id: 9216
376 | job_id: 8047
377 | status: COMPLETE
378 | - id: 33
379 | user_id: 3369
380 | job_id: 7438
381 | status: CANCELLED
382 | - id: 34
383 | user_id: 9825
384 | job_id: 6758
385 | status: PENDING
386 | - id: 35
387 | user_id: 3250
388 | job_id: 7760
389 | status: COMPLETE
390 | - id: 36
391 | user_id: 1552
392 | job_id: 4030
393 | status: COMPLETE
394 | - id: 37
395 | user_id: 9221
396 | job_id: 3971
397 | status: CANCELLED
398 | - id: 38
399 | user_id: 6816
400 | job_id: 7878
401 | status: PENDING
402 | - id: 39
403 | user_id: 6109
404 | job_id: 4060
405 | status: CANCELLED
406 | schema:
407 | type: object
408 | properties:
409 | items:
410 | type: array
411 | items:
412 | $ref: '#/components/schemas/JobApplication'
413 | /job-applications/{id}:
414 | parameters:
415 | - schema:
416 | type: integer
417 | name: id
418 | in: path
419 | required: true
420 | put:
421 | summary: Modify Job Application
422 | requestBody:
423 | description: Update the application details
424 | content:
425 | application/json:
426 | schema:
427 | $ref: '#/components/schemas/JobApplication'
428 |
429 | responses:
430 | '200':
431 | description: OK
432 | content:
433 | application/json:
434 | schema:
435 | type: array
436 | items:
437 | $ref: '#/components/schemas/JobApplication'
438 | components:
439 | schemas:
440 | User:
441 | type: object
442 | properties:
443 | id:
444 | type: integer
445 | email:
446 | type: string
447 | password:
448 | type: string
449 | full_name:
450 | type: string
451 | roles:
452 | type: array
453 | items:
454 | type: string
455 | Job:
456 | type: object
457 | properties:
458 | id:
459 | type: integer
460 | creator_user_id:
461 | type: integer
462 | start_time:
463 | type: string
464 | end_time:
465 | type: string
466 | activity:
467 | type: string
468 | dog:
469 | $ref: '#/components/schemas/Dog'
470 | Dog:
471 | type: object
472 | properties:
473 | name:
474 | type: string
475 | age:
476 | type: integer
477 | breed:
478 | type: string
479 | size:
480 | type: string
481 | JobApplication:
482 | type: object
483 | properties:
484 | id:
485 | type: integer
486 | status:
487 | type: string
488 | user_id:
489 | type: integer
490 | job_id:
491 | type: integer
492 |
--------------------------------------------------------------------------------
/ch13/01.yml:
--------------------------------------------------------------------------------
1 | openapi: 3.0.3
2 | info:
3 | title: PetSitter API
4 | version: "0.1"
5 | paths:
6 | /users:
7 | post:
8 | summary: Register User
9 | responses:
10 | '201':
11 | description: Created
12 | headers:
13 | Location:
14 | schema:
15 | type: string
16 | requestBody:
17 | content:
18 | application/json:
19 | schema:
20 | $ref: '#/components/schemas/User'
21 | /users/{id}:
22 | parameters:
23 | - schema:
24 | type: integer
25 | name: id
26 | in: path
27 | required: true
28 | get:
29 | summary: View User
30 | responses:
31 | '200':
32 | description: OK
33 | content:
34 | application/json:
35 | schema:
36 | $ref: '#/components/schemas/User'
37 | put:
38 | summary: Modify User
39 | responses:
40 | '200':
41 | description: OK
42 | content:
43 | application/json:
44 | schema:
45 | $ref: '#/components/schemas/User'
46 | requestBody:
47 | content:
48 | application/json:
49 | schema:
50 | $ref: '#/components/schemas/User'
51 | delete:
52 | summary: Delete User
53 | responses:
54 | '204':
55 | description: No Content
56 | /jobs:
57 | post:
58 | summary: Create Job
59 | responses:
60 | '201':
61 | description: Created
62 | headers:
63 | Location:
64 | schema:
65 | type: string
66 | requestBody:
67 | content:
68 | application/json:
69 | schema:
70 | $ref: '#/components/schemas/Job'
71 | get:
72 | summary: List All Jobs
73 | responses:
74 | '200':
75 | description: OK
76 | content:
77 | application/json:
78 | schema:
79 | type: object
80 | properties:
81 | items:
82 | type: array
83 | items:
84 | $ref: '#/components/schemas/Job'
85 | /jobs/{id}:
86 | parameters:
87 | - schema:
88 | type: integer
89 | name: id
90 | in: path
91 | required: true
92 | get:
93 | summary: View Job
94 | responses:
95 | '200':
96 | description: OK
97 | content:
98 | application/json:
99 | schema:
100 | $ref: '#/components/schemas/Job'
101 | put:
102 | summary: Modify Job
103 | responses:
104 | '200':
105 | description: OK
106 | content:
107 | application/json:
108 | schema:
109 | $ref: '#/components/schemas/Job'
110 | requestBody:
111 | content:
112 | application/json:
113 | schema:
114 | $ref: '#/components/schemas/Job'
115 | delete:
116 | summary: Delete Job
117 | responses:
118 | '204':
119 | description: No Content
120 | /jobs/{id}/job-applications:
121 | parameters:
122 | - schema:
123 | type: integer
124 | name: id
125 | in: path
126 | required: true
127 | get:
128 | summary: List Applications For Job
129 | responses:
130 | '200':
131 | description: OK
132 | content:
133 | application/json:
134 | schema:
135 | type: object
136 | properties:
137 | items:
138 | type: array
139 | items:
140 | $ref: '#/components/schemas/JobApplication'
141 | post:
142 | summary: Create Job Application
143 | responses:
144 | '201':
145 | description: Created
146 | headers:
147 | Location:
148 | schema:
149 | type: string
150 | requestBody:
151 | content:
152 | application/json:
153 | schema:
154 | $ref: '#/components/schemas/JobApplication'
155 | /users/{id}/jobs:
156 | parameters:
157 | - schema:
158 | type: integer
159 | name: id
160 | in: path
161 | required: true
162 | get:
163 | summary: List Jobs For User
164 | responses:
165 | '200':
166 | description: OK
167 | content:
168 | application/json:
169 | schema:
170 | type: object
171 | properties:
172 | items:
173 | type: array
174 | items:
175 | $ref: '#/components/schemas/Job'
176 | /job-applications/{id}:
177 | parameters:
178 | - schema:
179 | type: integer
180 | name: id
181 | in: path
182 | required: true
183 | put:
184 | summary: Modify Job Application
185 | requestBody:
186 | description: Update the application details
187 | content:
188 | application/json:
189 | schema:
190 | $ref: '#/components/schemas/JobApplication'
191 | responses:
192 | '200':
193 | description: OK
194 | content:
195 | application/json:
196 | schema:
197 | $ref: '#/components/schemas/JobApplication'
198 | components:
199 | schemas:
200 | User:
201 | type: object
202 | properties:
203 | id:
204 | type: integer
205 | email:
206 | type: string
207 | password:
208 | type: string
209 | full_name:
210 | type: string
211 | roles:
212 | type: array
213 | items:
214 | type: string
215 | Job:
216 | type: object
217 | properties:
218 | id:
219 | type: integer
220 | creator_user_id:
221 | type: integer
222 | start_time:
223 | type: string
224 | end_time:
225 | type: string
226 | activity:
227 | type: string
228 | dog:
229 | $ref: '#/components/schemas/Dog'
230 | Dog:
231 | type: object
232 | properties:
233 | name:
234 | type: string
235 | age:
236 | type: integer
237 | breed:
238 | type: string
239 | size:
240 | type: string
241 | JobApplication:
242 | type: object
243 | properties:
244 | id:
245 | type: integer
246 | status:
247 | type: string
248 | user_id:
249 | type: integer
250 | job_id:
251 | type: integer
252 |
--------------------------------------------------------------------------------
/ch13/02.yml:
--------------------------------------------------------------------------------
1 | openapi: 3.0.3
2 | info:
3 | title: PetSitter API
4 | version: "0.1"
5 | tags:
6 | - name: Users
7 | description: User-related operations
8 | - name: Jobs
9 | description: Job-related operations
10 | paths:
11 | /users:
12 | post:
13 | tags:
14 | - Users
15 | summary: Register User
16 | operationId: registerUser
17 | responses:
18 | '201':
19 | description: Created
20 | headers:
21 | Location:
22 | schema:
23 | type: string
24 | requestBody:
25 | content:
26 | application/json:
27 | schema:
28 | $ref: '#/components/schemas/User'
29 | /users/{id}:
30 | parameters:
31 | - schema:
32 | type: integer
33 | name: id
34 | in: path
35 | required: true
36 | get:
37 | tags:
38 | - Users
39 | summary: View User
40 | operationId: viewUserWithId
41 | responses:
42 | '200':
43 | description: OK
44 | content:
45 | application/json:
46 | schema:
47 | $ref: '#/components/schemas/User'
48 | put:
49 | tags:
50 | - Users
51 | summary: Modify User
52 | operationId: modifyUserWithId
53 | responses:
54 | '200':
55 | description: OK
56 | content:
57 | application/json:
58 | schema:
59 | $ref: '#/components/schemas/User'
60 | requestBody:
61 | content:
62 | application/json:
63 | schema:
64 | $ref: '#/components/schemas/User'
65 | delete:
66 | tags:
67 | - Users
68 | summary: Delete User
69 | operationId: deleteUserWithId
70 | responses:
71 | '204':
72 | description: No Content
73 | /jobs:
74 | post:
75 | tags:
76 | - Jobs
77 | summary: Create Job
78 | operationId: createJob
79 | responses:
80 | '201':
81 | description: Created
82 | headers:
83 | Location:
84 | schema:
85 | type: string
86 | requestBody:
87 | content:
88 | application/json:
89 | schema:
90 | $ref: '#/components/schemas/Job'
91 | get:
92 | tags:
93 | - Jobs
94 | summary: List All Jobs
95 | operationId: listAllJobs
96 | responses:
97 | '200':
98 | description: OK
99 | content:
100 | application/json:
101 | schema:
102 | type: object
103 | properties:
104 | items:
105 | type: array
106 | items:
107 | $ref: '#/components/schemas/Job'
108 | /jobs/{id}:
109 | parameters:
110 | - schema:
111 | type: integer
112 | name: id
113 | in: path
114 | required: true
115 | get:
116 | tags:
117 | - Jobs
118 | summary: View Job
119 | operationId: viewJobWithId
120 | responses:
121 | '200':
122 | description: OK
123 | content:
124 | application/json:
125 | schema:
126 | $ref: '#/components/schemas/Job'
127 | put:
128 | tags:
129 | - Jobs
130 | summary: Modify Job
131 | operationId: modifyJobWithId
132 | responses:
133 | '200':
134 | description: OK
135 | content:
136 | application/json:
137 | schema:
138 | $ref: '#/components/schemas/Job'
139 | requestBody:
140 | content:
141 | application/json:
142 | schema:
143 | $ref: '#/components/schemas/Job'
144 | delete:
145 | tags:
146 | - Jobs
147 | summary: Delete Job
148 | operationId: deleteJobWithId
149 | responses:
150 | '204':
151 | description: No Content
152 | /jobs/{id}/job-applications:
153 | parameters:
154 | - schema:
155 | type: integer
156 | name: id
157 | in: path
158 | required: true
159 | get:
160 | tags:
161 | - Jobs
162 | summary: List Applications For Job
163 | operationId: viewApplicationsForJob
164 | responses:
165 | '200':
166 | description: OK
167 | content:
168 | application/json:
169 | schema:
170 | type: object
171 | properties:
172 | items:
173 | type: array
174 | items:
175 | $ref: '#/components/schemas/JobApplication'
176 | post:
177 | tags:
178 | - Jobs
179 | summary: Create Job Application
180 | operationId: createJobApplication
181 | responses:
182 | '201':
183 | description: Created
184 | headers:
185 | Location:
186 | schema:
187 | type: string
188 | requestBody:
189 | content:
190 | application/json:
191 | schema:
192 | $ref: '#/components/schemas/JobApplication'
193 | /users/{id}/jobs:
194 | parameters:
195 | - schema:
196 | type: integer
197 | name: id
198 | in: path
199 | required: true
200 | get:
201 | tags:
202 | - Users
203 | summary: List Jobs For User
204 | operationId: listJobsForUser
205 | responses:
206 | '200':
207 | description: OK
208 | content:
209 | application/json:
210 | schema:
211 | type: object
212 | properties:
213 | items:
214 | type: array
215 | items:
216 | $ref: '#/components/schemas/Job'
217 | /job-applications/{id}:
218 | parameters:
219 | - schema:
220 | type: integer
221 | name: id
222 | in: path
223 | required: true
224 | put:
225 | tags:
226 | - Jobs
227 | summary: Modify Job Application
228 | operationId: modifyJobApplicationWithId
229 | requestBody:
230 | description: Update the application details
231 | content:
232 | application/json:
233 | schema:
234 | $ref: '#/components/schemas/JobApplication'
235 | responses:
236 | '200':
237 | description: OK
238 | content:
239 | application/json:
240 | schema:
241 | $ref: '#/components/schemas/JobApplication'
242 | components:
243 | schemas:
244 | User:
245 | type: object
246 | properties:
247 | id:
248 | type: integer
249 | email:
250 | type: string
251 | password:
252 | type: string
253 | full_name:
254 | type: string
255 | roles:
256 | type: array
257 | items:
258 | type: string
259 | Job:
260 | type: object
261 | properties:
262 | id:
263 | type: integer
264 | creator_user_id:
265 | type: integer
266 | start_time:
267 | type: string
268 | end_time:
269 | type: string
270 | activity:
271 | type: string
272 | dog:
273 | $ref: '#/components/schemas/Dog'
274 | Dog:
275 | type: object
276 | properties:
277 | name:
278 | type: string
279 | age:
280 | type: integer
281 | breed:
282 | type: string
283 | size:
284 | type: string
285 | JobApplication:
286 | type: object
287 | properties:
288 | id:
289 | type: integer
290 | status:
291 | type: string
292 | user_id:
293 | type: integer
294 | job_id:
295 | type: integer
296 |
--------------------------------------------------------------------------------
/ch13/README.md:
--------------------------------------------------------------------------------
1 | # Chapter 13: Building a Backend with Node.js and Swagger Codegen
2 |
3 | The file [01.yml](01.yml) contains the base OpenAPI file from [chapter 11](https://livebook.manning.com/book/designing-apis-with-swagger-and-openapi/chapter-11).
4 |
5 | The file [02.yml](02.yml) contains the OpenAPI file for the PetSitter project after the operation IDs and tags were added in [chapter 13](https://livebook.manning.com/book/designing-apis-with-swagger-and-openapi/chapter-13).
6 |
7 | The file [openapi.yml](openapi.yml) contains the OpenAPI file for the PetSitter project after the additional data type changes made in [chapter 13](https://livebook.manning.com/book/designing-apis-with-swagger-and-openapi/chapter-13) and represents the state at the end of the chapter.
8 |
--------------------------------------------------------------------------------
/ch13/openapi.yml:
--------------------------------------------------------------------------------
1 | openapi: 3.0.3
2 | info:
3 | title: PetSitter API
4 | version: "0.1"
5 | tags:
6 | - name: Users
7 | description: User-related operations
8 | - name: Jobs
9 | description: Job-related operations
10 | paths:
11 | /users:
12 | post:
13 | tags:
14 | - Users
15 | summary: Register User
16 | operationId: registerUser
17 | responses:
18 | '201':
19 | description: Created
20 | headers:
21 | Location:
22 | schema:
23 | type: string
24 | requestBody:
25 | content:
26 | application/json:
27 | schema:
28 | $ref: '#/components/schemas/User'
29 | /users/{id}:
30 | parameters:
31 | - schema:
32 | type: string
33 | name: id
34 | in: path
35 | required: true
36 | get:
37 | tags:
38 | - Users
39 | summary: View User
40 | operationId: viewUserWithId
41 | responses:
42 | '200':
43 | description: OK
44 | content:
45 | application/json:
46 | schema:
47 | $ref: '#/components/schemas/User'
48 | put:
49 | tags:
50 | - Users
51 | summary: Modify User
52 | operationId: modifyUserWithId
53 | responses:
54 | '200':
55 | description: OK
56 | content:
57 | application/json:
58 | schema:
59 | $ref: '#/components/schemas/User'
60 | requestBody:
61 | content:
62 | application/json:
63 | schema:
64 | $ref: '#/components/schemas/User'
65 | delete:
66 | tags:
67 | - Users
68 | summary: Delete User
69 | operationId: deleteUserWithId
70 | responses:
71 | '204':
72 | description: No Content
73 | /jobs:
74 | post:
75 | tags:
76 | - Jobs
77 | summary: Create Job
78 | operationId: createJob
79 | responses:
80 | '201':
81 | description: Created
82 | headers:
83 | Location:
84 | schema:
85 | type: string
86 | requestBody:
87 | content:
88 | application/json:
89 | schema:
90 | $ref: '#/components/schemas/Job'
91 | get:
92 | tags:
93 | - Jobs
94 | summary: List All Jobs
95 | operationId: listAllJobs
96 | responses:
97 | '200':
98 | description: OK
99 | content:
100 | application/json:
101 | schema:
102 | type: object
103 | properties:
104 | items:
105 | type: array
106 | items:
107 | $ref: '#/components/schemas/Job'
108 | /jobs/{id}:
109 | parameters:
110 | - schema:
111 | type: string
112 | name: id
113 | in: path
114 | required: true
115 | get:
116 | tags:
117 | - Jobs
118 | summary: View Job
119 | operationId: viewJobWithId
120 | responses:
121 | '200':
122 | description: OK
123 | content:
124 | application/json:
125 | schema:
126 | $ref: '#/components/schemas/Job'
127 | put:
128 | tags:
129 | - Jobs
130 | summary: Modify Job
131 | operationId: modifyJobWithId
132 | responses:
133 | '200':
134 | description: OK
135 | content:
136 | application/json:
137 | schema:
138 | $ref: '#/components/schemas/Job'
139 | requestBody:
140 | content:
141 | application/json:
142 | schema:
143 | $ref: '#/components/schemas/Job'
144 | delete:
145 | tags:
146 | - Jobs
147 | summary: Delete Job
148 | operationId: deleteJobWithId
149 | responses:
150 | '204':
151 | description: No Content
152 | /jobs/{id}/job-applications:
153 | parameters:
154 | - schema:
155 | type: string
156 | name: id
157 | in: path
158 | required: true
159 | get:
160 | tags:
161 | - Jobs
162 | summary: List Applications For Job
163 | operationId: viewApplicationsForJob
164 | responses:
165 | '200':
166 | description: OK
167 | content:
168 | application/json:
169 | schema:
170 | type: object
171 | properties:
172 | items:
173 | type: array
174 | items:
175 | $ref: '#/components/schemas/JobApplication'
176 | post:
177 | tags:
178 | - Jobs
179 | summary: Create Job Application
180 | operationId: createJobApplication
181 | responses:
182 | '201':
183 | description: Created
184 | headers:
185 | Location:
186 | schema:
187 | type: string
188 | requestBody:
189 | content:
190 | application/json:
191 | schema:
192 | $ref: '#/components/schemas/JobApplication'
193 | /users/{id}/jobs:
194 | parameters:
195 | - schema:
196 | type: string
197 | name: id
198 | in: path
199 | required: true
200 | get:
201 | tags:
202 | - Users
203 | summary: List Jobs For User
204 | operationId: listJobsForUser
205 | responses:
206 | '200':
207 | description: OK
208 | content:
209 | application/json:
210 | schema:
211 | type: object
212 | properties:
213 | items:
214 | type: array
215 | items:
216 | $ref: '#/components/schemas/Job'
217 | /job-applications/{id}:
218 | parameters:
219 | - schema:
220 | type: string
221 | name: id
222 | in: path
223 | required: true
224 | put:
225 | tags:
226 | - Jobs
227 | summary: Modify Job Application
228 | operationId: modifyJobApplicationWithId
229 | requestBody:
230 | description: Update the application details
231 | content:
232 | application/json:
233 | schema:
234 | $ref: '#/components/schemas/JobApplication'
235 | responses:
236 | '200':
237 | description: OK
238 | content:
239 | application/json:
240 | schema:
241 | $ref: '#/components/schemas/JobApplication'
242 | components:
243 | schemas:
244 | User:
245 | type: object
246 | properties:
247 | id:
248 | type: string
249 | email:
250 | type: string
251 | password:
252 | type: string
253 | full_name:
254 | type: string
255 | roles:
256 | type: array
257 | items:
258 | type: string
259 | Job:
260 | type: object
261 | properties:
262 | id:
263 | type: string
264 | creator_user_id:
265 | type: string
266 | start_time:
267 | type: string
268 | end_time:
269 | type: string
270 | activity:
271 | type: string
272 | dog:
273 | $ref: '#/components/schemas/Dog'
274 | Dog:
275 | type: object
276 | properties:
277 | name:
278 | type: string
279 | age:
280 | type: integer
281 | breed:
282 | type: string
283 | size:
284 | type: string
285 | JobApplication:
286 | type: object
287 | properties:
288 | id:
289 | type: string
290 | status:
291 | type: string
292 | user_id:
293 | type: string
294 | job_id:
295 | type: string
296 |
--------------------------------------------------------------------------------
/ch14/01.yml:
--------------------------------------------------------------------------------
1 | openapi: 3.0.3
2 | info:
3 | title: PetSitter API
4 | version: "0.1"
5 | tags:
6 | - name: Users
7 | description: User-related operations
8 | - name: Jobs
9 | description: Job-related operations
10 | paths:
11 | /users:
12 | post:
13 | tags:
14 | - Users
15 | summary: Register User
16 | operationId: registerUser
17 | responses:
18 | '201':
19 | description: Created
20 | headers:
21 | Location:
22 | schema:
23 | type: string
24 | requestBody:
25 | content:
26 | application/json:
27 | schema:
28 | $ref: '#/components/schemas/User'
29 | /users/{id}:
30 | parameters:
31 | - schema:
32 | type: string
33 | name: id
34 | in: path
35 | required: true
36 | get:
37 | tags:
38 | - Users
39 | summary: View User
40 | operationId: viewUserWithId
41 | responses:
42 | '200':
43 | description: OK
44 | content:
45 | application/json:
46 | schema:
47 | $ref: '#/components/schemas/User'
48 | put:
49 | tags:
50 | - Users
51 | summary: Modify User
52 | operationId: modifyUserWithId
53 | responses:
54 | '200':
55 | description: OK
56 | content:
57 | application/json:
58 | schema:
59 | $ref: '#/components/schemas/User'
60 | requestBody:
61 | content:
62 | application/json:
63 | schema:
64 | $ref: '#/components/schemas/User'
65 | delete:
66 | tags:
67 | - Users
68 | summary: Delete User
69 | operationId: deleteUserWithId
70 | responses:
71 | '204':
72 | description: No Content
73 | /jobs:
74 | post:
75 | tags:
76 | - Jobs
77 | summary: Create Job
78 | operationId: createJob
79 | responses:
80 | '201':
81 | description: Created
82 | headers:
83 | Location:
84 | schema:
85 | type: string
86 | requestBody:
87 | content:
88 | application/json:
89 | schema:
90 | $ref: '#/components/schemas/Job'
91 | get:
92 | tags:
93 | - Jobs
94 | summary: List All Jobs
95 | operationId: listAllJobs
96 | responses:
97 | '200':
98 | description: OK
99 | content:
100 | application/json:
101 | schema:
102 | type: object
103 | properties:
104 | items:
105 | type: array
106 | items:
107 | $ref: '#/components/schemas/Job'
108 | examples:
109 | with-some-data:
110 | summary: With some data
111 | value:
112 | items:
113 | - id: 123
114 | creator_user_id: 345
115 | start_time: 2020-06-01T00:00:00Z
116 | end_time: 2020-06-02T00:00:00Z
117 | dog:
118 | name: Fido
119 | age: 3
120 | breed: Doberman
121 | size: medium
122 | activity: walk
123 | - id: 234
124 | creator_user_id: 345
125 | start_time: 2020-06-01T00:00:00Z
126 | end_time: 2020-06-03T00:00:00Z
127 | dog:
128 | name: Rex
129 | age: 2
130 | breed: Rottweiler
131 | size: large
132 | activity: sit
133 | - id: 234
134 | creator_user_id: 345
135 | start_time: 2020-06-01T00:00:00Z
136 | end_time: 2020-06-02T00:00:00Z
137 | dog:
138 | name: Blossom
139 | age: 2
140 | breed: Rottweiler
141 | size: large
142 | activity: walk
143 | /jobs/{id}:
144 | parameters:
145 | - schema:
146 | type: string
147 | name: id
148 | in: path
149 | required: true
150 | get:
151 | tags:
152 | - Jobs
153 | summary: View Job
154 | operationId: viewJobWithId
155 | responses:
156 | '200':
157 | description: OK
158 | content:
159 | application/json:
160 | schema:
161 | $ref: '#/components/schemas/Job'
162 | put:
163 | tags:
164 | - Jobs
165 | summary: Modify Job
166 | operationId: modifyJobWithId
167 | responses:
168 | '200':
169 | description: OK
170 | content:
171 | application/json:
172 | schema:
173 | $ref: '#/components/schemas/Job'
174 | requestBody:
175 | content:
176 | application/json:
177 | schema:
178 | $ref: '#/components/schemas/Job'
179 | delete:
180 | tags:
181 | - Jobs
182 | summary: Delete Job
183 | operationId: deleteJobWithId
184 | responses:
185 | '204':
186 | description: No Content
187 | /jobs/{id}/job-applications:
188 | parameters:
189 | - schema:
190 | type: string
191 | name: id
192 | in: path
193 | required: true
194 | get:
195 | tags:
196 | - Jobs
197 | summary: List Applications For Job
198 | operationId: viewApplicationsForJob
199 | responses:
200 | '200':
201 | description: OK
202 | content:
203 | application/json:
204 | examples:
205 | empty:
206 | summary: Zero Job Applications
207 | value:
208 | items: []
209 | two-items:
210 | summary: Two Job Applications
211 | value:
212 | items:
213 | - id: 123
214 | user_id: 123
215 | job_id: 123
216 | status: PENDING
217 | - id: 123
218 | user_id: 123
219 | job_id: 123
220 | status: COMPLETE
221 | many:
222 | summary: Many Job Applications
223 | value:
224 | items:
225 | - id: 0
226 | user_id: 358
227 | job_id: 4012
228 | status: COMPLETE
229 | - id: 1
230 | user_id: 3089
231 | job_id: 3902
232 | status: PENDING
233 | - id: 2
234 | user_id: 4040
235 | job_id: 5269
236 | status: PENDING
237 | - id: 3
238 | user_id: 5636
239 | job_id: 8420
240 | status: PENDING
241 | - id: 4
242 | user_id: 9540
243 | job_id: 9505
244 | status: COMPLETE
245 | - id: 5
246 | user_id: 9873
247 | job_id: 3215
248 | status: PENDING
249 | - id: 6
250 | user_id: 6032
251 | job_id: 7365
252 | status: COMPLETE
253 | - id: 7
254 | user_id: 5999
255 | job_id: 1159
256 | status: COMPLETE
257 | - id: 8
258 | user_id: 2897
259 | job_id: 7982
260 | status: COMPLETE
261 | - id: 9
262 | user_id: 227
263 | job_id: 9245
264 | status: CANCELLED
265 | - id: 10
266 | user_id: 741
267 | job_id: 2752
268 | status: CANCELLED
269 | - id: 11
270 | user_id: 9059
271 | job_id: 338
272 | status: PENDING
273 | - id: 12
274 | user_id: 1379
275 | job_id: 4531
276 | status: COMPLETE
277 | - id: 13
278 | user_id: 2031
279 | job_id: 9375
280 | status: COMPLETE
281 | - id: 14
282 | user_id: 3643
283 | job_id: 5175
284 | status: CANCELLED
285 | - id: 15
286 | user_id: 5470
287 | job_id: 831
288 | status: CANCELLED
289 | - id: 16
290 | user_id: 3265
291 | job_id: 5597
292 | status: PENDING
293 | - id: 17
294 | user_id: 2815
295 | job_id: 7719
296 | status: PENDING
297 | - id: 18
298 | user_id: 8306
299 | job_id: 679
300 | status: PENDING
301 | - id: 19
302 | user_id: 9742
303 | job_id: 8239
304 | status: PENDING
305 | - id: 20
306 | user_id: 4851
307 | job_id: 940
308 | status: PENDING
309 | - id: 21
310 | user_id: 6700
311 | job_id: 4040
312 | status: PENDING
313 | - id: 22
314 | user_id: 7067
315 | job_id: 6016
316 | status: PENDING
317 | - id: 23
318 | user_id: 3265
319 | job_id: 1822
320 | status: PENDING
321 | - id: 24
322 | user_id: 8333
323 | job_id: 9988
324 | status: PENDING
325 | - id: 25
326 | user_id: 7543
327 | job_id: 9307
328 | status: PENDING
329 | - id: 26
330 | user_id: 5429
331 | job_id: 7511
332 | status: COMPLETE
333 | - id: 27
334 | user_id: 3576
335 | job_id: 1710
336 | status: PENDING
337 | - id: 28
338 | user_id: 590
339 | job_id: 2634
340 | status: COMPLETE
341 | - id: 29
342 | user_id: 2327
343 | job_id: 7205
344 | status: CANCELLED
345 | - id: 30
346 | user_id: 2193
347 | job_id: 7421
348 | status: COMPLETE
349 | - id: 31
350 | user_id: 5014
351 | job_id: 6781
352 | status: CANCELLED
353 | - id: 32
354 | user_id: 9216
355 | job_id: 8047
356 | status: COMPLETE
357 | - id: 33
358 | user_id: 3369
359 | job_id: 7438
360 | status: CANCELLED
361 | - id: 34
362 | user_id: 9825
363 | job_id: 6758
364 | status: PENDING
365 | - id: 35
366 | user_id: 3250
367 | job_id: 7760
368 | status: COMPLETE
369 | - id: 36
370 | user_id: 1552
371 | job_id: 4030
372 | status: COMPLETE
373 | - id: 37
374 | user_id: 9221
375 | job_id: 3971
376 | status: CANCELLED
377 | - id: 38
378 | user_id: 6816
379 | job_id: 7878
380 | status: PENDING
381 | - id: 39
382 | user_id: 6109
383 | job_id: 4060
384 | status: CANCELLED
385 | schema:
386 | type: object
387 | properties:
388 | items:
389 | type: array
390 | items:
391 | $ref: '#/components/schemas/JobApplication'
392 | post:
393 | tags:
394 | - Jobs
395 | summary: Create Job Application
396 | operationId: createJobApplication
397 | responses:
398 | '201':
399 | description: Created
400 | headers:
401 | Location:
402 | schema:
403 | type: string
404 | requestBody:
405 | content:
406 | application/json:
407 | schema:
408 | $ref: '#/components/schemas/JobApplication'
409 | /users/{id}/jobs:
410 | parameters:
411 | - schema:
412 | type: string
413 | name: id
414 | in: path
415 | required: true
416 | get:
417 | tags:
418 | - Users
419 | summary: List Jobs For User
420 | operationId: listJobsForUser
421 | responses:
422 | '200':
423 | description: OK
424 | content:
425 | application/json:
426 | schema:
427 | type: object
428 | properties:
429 | items:
430 | type: array
431 | items:
432 | $ref: '#/components/schemas/Job'
433 | /users/{id}/job-applications:
434 | parameters:
435 | - name: id
436 | in: path
437 | required: true
438 | schema:
439 | type: integer
440 | get:
441 | summary: List Applications For User
442 | responses:
443 | '200':
444 | description: OK
445 | content:
446 | application/json:
447 | examples:
448 | empty:
449 | summary: Zero Job Applications
450 | value:
451 | items: []
452 | two-items:
453 | summary: Two Job Applications
454 | value:
455 | items:
456 | - id: 123
457 | user_id: 123
458 | job_id: 123
459 | status: PENDING
460 | - id: 123
461 | user_id: 123
462 | job_id: 123
463 | status: COMPLETE
464 | many:
465 | summary: Many Job Applications
466 | value:
467 | items:
468 | - id: 0
469 | user_id: 358
470 | job_id: 4012
471 | status: COMPLETE
472 | - id: 1
473 | user_id: 3089
474 | job_id: 3902
475 | status: PENDING
476 | - id: 2
477 | user_id: 4040
478 | job_id: 5269
479 | status: PENDING
480 | - id: 3
481 | user_id: 5636
482 | job_id: 8420
483 | status: PENDING
484 | - id: 4
485 | user_id: 9540
486 | job_id: 9505
487 | status: COMPLETE
488 | - id: 5
489 | user_id: 9873
490 | job_id: 3215
491 | status: PENDING
492 | - id: 6
493 | user_id: 6032
494 | job_id: 7365
495 | status: COMPLETE
496 | - id: 7
497 | user_id: 5999
498 | job_id: 1159
499 | status: COMPLETE
500 | - id: 8
501 | user_id: 2897
502 | job_id: 7982
503 | status: COMPLETE
504 | - id: 9
505 | user_id: 227
506 | job_id: 9245
507 | status: CANCELLED
508 | - id: 10
509 | user_id: 741
510 | job_id: 2752
511 | status: CANCELLED
512 | - id: 11
513 | user_id: 9059
514 | job_id: 338
515 | status: PENDING
516 | - id: 12
517 | user_id: 1379
518 | job_id: 4531
519 | status: COMPLETE
520 | - id: 13
521 | user_id: 2031
522 | job_id: 9375
523 | status: COMPLETE
524 | - id: 14
525 | user_id: 3643
526 | job_id: 5175
527 | status: CANCELLED
528 | - id: 15
529 | user_id: 5470
530 | job_id: 831
531 | status: CANCELLED
532 | - id: 16
533 | user_id: 3265
534 | job_id: 5597
535 | status: PENDING
536 | - id: 17
537 | user_id: 2815
538 | job_id: 7719
539 | status: PENDING
540 | - id: 18
541 | user_id: 8306
542 | job_id: 679
543 | status: PENDING
544 | - id: 19
545 | user_id: 9742
546 | job_id: 8239
547 | status: PENDING
548 | - id: 20
549 | user_id: 4851
550 | job_id: 940
551 | status: PENDING
552 | - id: 21
553 | user_id: 6700
554 | job_id: 4040
555 | status: PENDING
556 | - id: 22
557 | user_id: 7067
558 | job_id: 6016
559 | status: PENDING
560 | - id: 23
561 | user_id: 3265
562 | job_id: 1822
563 | status: PENDING
564 | - id: 24
565 | user_id: 8333
566 | job_id: 9988
567 | status: PENDING
568 | - id: 25
569 | user_id: 7543
570 | job_id: 9307
571 | status: PENDING
572 | - id: 26
573 | user_id: 5429
574 | job_id: 7511
575 | status: COMPLETE
576 | - id: 27
577 | user_id: 3576
578 | job_id: 1710
579 | status: PENDING
580 | - id: 28
581 | user_id: 590
582 | job_id: 2634
583 | status: COMPLETE
584 | - id: 29
585 | user_id: 2327
586 | job_id: 7205
587 | status: CANCELLED
588 | - id: 30
589 | user_id: 2193
590 | job_id: 7421
591 | status: COMPLETE
592 | - id: 31
593 | user_id: 5014
594 | job_id: 6781
595 | status: CANCELLED
596 | - id: 32
597 | user_id: 9216
598 | job_id: 8047
599 | status: COMPLETE
600 | - id: 33
601 | user_id: 3369
602 | job_id: 7438
603 | status: CANCELLED
604 | - id: 34
605 | user_id: 9825
606 | job_id: 6758
607 | status: PENDING
608 | - id: 35
609 | user_id: 3250
610 | job_id: 7760
611 | status: COMPLETE
612 | - id: 36
613 | user_id: 1552
614 | job_id: 4030
615 | status: COMPLETE
616 | - id: 37
617 | user_id: 9221
618 | job_id: 3971
619 | status: CANCELLED
620 | - id: 38
621 | user_id: 6816
622 | job_id: 7878
623 | status: PENDING
624 | - id: 39
625 | user_id: 6109
626 | job_id: 4060
627 | status: CANCELLED
628 | schema:
629 | type: object
630 | properties:
631 | items:
632 | type: array
633 | items:
634 | $ref: '#/components/schemas/JobApplication'
635 | /job-applications/{id}:
636 | parameters:
637 | - schema:
638 | type: string
639 | name: id
640 | in: path
641 | required: true
642 | put:
643 | tags:
644 | - Jobs
645 | summary: Modify Job Application
646 | operationId: modifyJobApplicationWithId
647 | requestBody:
648 | description: Update the application details
649 | content:
650 | application/json:
651 | schema:
652 | $ref: '#/components/schemas/JobApplication'
653 | responses:
654 | '200':
655 | description: OK
656 | content:
657 | application/json:
658 | schema:
659 | $ref: '#/components/schemas/JobApplication'
660 | components:
661 | schemas:
662 | User:
663 | type: object
664 | properties:
665 | id:
666 | type: string
667 | email:
668 | type: string
669 | password:
670 | type: string
671 | full_name:
672 | type: string
673 | roles:
674 | type: array
675 | items:
676 | type: string
677 | Job:
678 | type: object
679 | properties:
680 | id:
681 | type: string
682 | creator_user_id:
683 | type: string
684 | start_time:
685 | type: string
686 | end_time:
687 | type: string
688 | activity:
689 | type: string
690 | dog:
691 | $ref: '#/components/schemas/Dog'
692 | Dog:
693 | type: object
694 | properties:
695 | name:
696 | type: string
697 | age:
698 | type: integer
699 | breed:
700 | type: string
701 | size:
702 | type: string
703 | JobApplication:
704 | type: object
705 | properties:
706 | id:
707 | type: string
708 | status:
709 | type: string
710 | user_id:
711 | type: string
712 | job_id:
713 | type: string
--------------------------------------------------------------------------------
/ch14/README.md:
--------------------------------------------------------------------------------
1 | # Chapter 14: Integrating and releasing the web application
2 |
3 | The file [openapi-merged.yaml](openapi-merged.yaml) contains the OpenAPI file for the PetSitter project in its state at the beginning of [chapter 14](https://livebook.manning.com/book/designing-apis-with-swagger-and-openapi/chapter-14) after combining the changes from chapter 12 and 13.
4 |
5 | The file [openapi.yaml](openapi.yaml) contains the OpenAPI file for the PetSitter project in its state at the end of [chapter 14](https://livebook.manning.com/book/designing-apis-with-swagger-and-openapi/chapter-14) when security was added.
--------------------------------------------------------------------------------
/ch16/README.md:
--------------------------------------------------------------------------------
1 | # Chapter 16: Designing the next API iteration
2 |
3 | The file [openapi.yaml](openapi.yaml) contains the OpenAPI file for the PetSitter project after the updates made in [chapter 16](https://livebook.manning.com/book/designing-apis-with-swagger-and-openapi/chapter-16).
--------------------------------------------------------------------------------
/ch16/openapi.yaml:
--------------------------------------------------------------------------------
1 | openapi: 3.0.0
2 | info:
3 | title: PetSitter API
4 | version: "0.1"
5 | tags:
6 | - name: Users
7 | description: User-related operations
8 | - name: Jobs
9 | description: Job-related operations
10 | paths:
11 | /users:
12 | post:
13 | tags:
14 | - Users
15 | summary: Register User
16 | operationId: registerUser
17 | responses:
18 | '201':
19 | description: Created
20 | headers:
21 | Location:
22 | schema:
23 | type: string
24 | requestBody:
25 | content:
26 | application/json:
27 | schema:
28 | $ref: '#/components/schemas/User'
29 | security: []
30 | /users/{id}:
31 | parameters:
32 | - schema:
33 | type: string
34 | name: id
35 | in: path
36 | required: true
37 | get:
38 | tags:
39 | - Users
40 | summary: View User
41 | operationId: viewUserWithId
42 | responses:
43 | '200':
44 | description: OK
45 | content:
46 | application/json:
47 | schema:
48 | $ref: '#/components/schemas/User'
49 | put:
50 | tags:
51 | - Users
52 | summary: Modify User
53 | operationId: modifyUserWithId
54 | responses:
55 | '200':
56 | description: OK
57 | content:
58 | application/json:
59 | schema:
60 | $ref: '#/components/schemas/User'
61 | requestBody:
62 | content:
63 | application/json:
64 | schema:
65 | $ref: '#/components/schemas/User'
66 | delete:
67 | tags:
68 | - Users
69 | summary: Delete User
70 | operationId: deleteUserWithId
71 | responses:
72 | '204':
73 | description: No Content
74 | /jobs:
75 | post:
76 | tags:
77 | - Jobs
78 | summary: Create Job
79 | operationId: createJob
80 | responses:
81 | '201':
82 | description: Created
83 | headers:
84 | Location:
85 | schema:
86 | type: string
87 | requestBody:
88 | content:
89 | application/json:
90 | schema:
91 | $ref: '#/components/schemas/Job'
92 | get:
93 | tags:
94 | - Jobs
95 | summary: List All Jobs
96 | operationId: listAllJobs
97 | responses:
98 | '200':
99 | description: OK
100 | content:
101 | application/json:
102 | schema:
103 | type: object
104 | properties:
105 | items:
106 | type: array
107 | items:
108 | $ref: '#/components/schemas/Job'
109 | /jobs/{id}:
110 | parameters:
111 | - schema:
112 | type: string
113 | name: id
114 | in: path
115 | required: true
116 | get:
117 | tags:
118 | - Jobs
119 | summary: View Job
120 | operationId: viewJobWithId
121 | responses:
122 | '200':
123 | description: OK
124 | content:
125 | application/json:
126 | schema:
127 | $ref: '#/components/schemas/Job'
128 | put:
129 | tags:
130 | - Jobs
131 | summary: Modify Job
132 | operationId: modifyJobWithId
133 | responses:
134 | '200':
135 | description: OK
136 | content:
137 | application/json:
138 | schema:
139 | $ref: '#/components/schemas/Job'
140 | requestBody:
141 | content:
142 | application/json:
143 | schema:
144 | $ref: '#/components/schemas/Job'
145 | delete:
146 | tags:
147 | - Jobs
148 | summary: Delete Job
149 | operationId: deleteJobWithId
150 | responses:
151 | '204':
152 | description: No Content
153 | /jobs/{id}/job-applications:
154 | parameters:
155 | - schema:
156 | type: string
157 | name: id
158 | in: path
159 | required: true
160 | get:
161 | tags:
162 | - Jobs
163 | summary: List Applications For Job
164 | operationId: viewApplicationsForJob
165 | responses:
166 | '200':
167 | description: OK
168 | content:
169 | application/json:
170 | schema:
171 | type: object
172 | properties:
173 | items:
174 | type: array
175 | items:
176 | $ref: '#/components/schemas/JobApplication'
177 | post:
178 | tags:
179 | - Jobs
180 | summary: Create Job Application
181 | operationId: createJobApplication
182 | responses:
183 | '201':
184 | description: Created
185 | headers:
186 | Location:
187 | schema:
188 | type: string
189 | requestBody:
190 | content:
191 | application/json:
192 | schema:
193 | $ref: '#/components/schemas/JobApplication'
194 | /users/{id}/jobs:
195 | parameters:
196 | - schema:
197 | type: string
198 | name: id
199 | in: path
200 | required: true
201 | get:
202 | tags:
203 | - Users
204 | summary: List Jobs For User
205 | operationId: listJobsForUser
206 | responses:
207 | '200':
208 | description: OK
209 | content:
210 | application/json:
211 | schema:
212 | type: object
213 | properties:
214 | items:
215 | type: array
216 | items:
217 | $ref: '#/components/schemas/Job'
218 | /users/{id}/job-applications:
219 | parameters:
220 | - name: id
221 | in: path
222 | required: true
223 | schema:
224 | type: integer
225 | get:
226 | tags:
227 | - Users
228 | summary: List Applications For User
229 | operationId: viewApplicationsForUser
230 | responses:
231 | '200':
232 | description: OK
233 | content:
234 | application/json:
235 | schema:
236 | type: object
237 | properties:
238 | items:
239 | type: array
240 | items:
241 | $ref: '#/components/schemas/JobApplication'
242 | /job-applications/{id}:
243 | parameters:
244 | - schema:
245 | type: string
246 | name: id
247 | in: path
248 | required: true
249 | put:
250 | tags:
251 | - Jobs
252 | summary: Modify Job Application
253 | operationId: modifyJobApplicationWithId
254 | requestBody:
255 | description: Update the application details
256 | content:
257 | application/json:
258 | schema:
259 | $ref: '#/components/schemas/JobApplication'
260 | responses:
261 | '200':
262 | description: OK
263 | content:
264 | application/json:
265 | schema:
266 | type: array
267 | items:
268 | $ref: '#/components/schemas/JobApplication'
269 | /sessions:
270 | post:
271 | tags:
272 | - Users
273 | summary: Start Session (Login)
274 | operationId: startSession
275 | responses:
276 | '200':
277 | description: OK
278 | content:
279 | application/json:
280 | schema:
281 | $ref: '#/components/schemas/Session'
282 | requestBody:
283 | content:
284 | application/json:
285 | schema:
286 | type: object
287 | properties:
288 | email:
289 | type: string
290 | password:
291 | type: string
292 | security: []
293 | components:
294 | schemas:
295 | User:
296 | type: object
297 | properties:
298 | id:
299 | type: string
300 | email:
301 | type: string
302 | password:
303 | type: string
304 | full_name:
305 | type: string
306 | roles:
307 | type: array
308 | items:
309 | type: string
310 | Job:
311 | type: object
312 | properties:
313 | id:
314 | type: string
315 | creator_user_id:
316 | type: string
317 | start_time:
318 | type: string
319 | end_time:
320 | type: string
321 | activity:
322 | type: string
323 | pets:
324 | type: array
325 | items:
326 | $ref: '#/components/schemas/Pet'
327 | Dog:
328 | type: object
329 | properties:
330 | species:
331 | type: string
332 | breed:
333 | type: string
334 | size:
335 | type: string
336 | required:
337 | - species
338 | Cat:
339 | type: object
340 | properties:
341 | species:
342 | type: string
343 | breed:
344 | type: string
345 | required:
346 | - species
347 | Pet:
348 | allOf:
349 | - type: object
350 | properties:
351 | name:
352 | type: string
353 | age:
354 | type: integer
355 | - oneOf:
356 | - $ref: '#/components/schemas/Cat'
357 | - $ref: '#/components/schemas/Dog'
358 | discriminator:
359 | propertyName: species
360 | mapping:
361 | Cat: '#/components/schemas/Cat'
362 | Dog: '#/components/schemas/Dog'
363 | JobApplication:
364 | type: object
365 | properties:
366 | id:
367 | type: string
368 | status:
369 | type: string
370 | user_id:
371 | type: string
372 | job_id:
373 | type: string
374 | Session:
375 | type: object
376 | properties:
377 | user_id:
378 | type: string
379 | auth_header:
380 | type: string
381 | securitySchemes:
382 | SessionToken:
383 | type: apiKey
384 | in: header
385 | name: Authorization
386 | security:
387 | - SessionToken: []
388 |
--------------------------------------------------------------------------------
/ch17/README.md:
--------------------------------------------------------------------------------
1 | # Chapter 17: Scaling collection endpoints with filters and pagination
2 |
3 | The file [openapi.yaml](openapi.yaml) contains the OpenAPI file for the PetSitter project after the updates made in [chapter 17](https://livebook.manning.com/book/designing-apis-with-swagger-and-openapi/chapter-17).
--------------------------------------------------------------------------------
/ch17/openapi.yaml:
--------------------------------------------------------------------------------
1 | openapi: 3.0.0
2 | info:
3 | title: PetSitter API
4 | version: "0.1"
5 | tags:
6 | - name: Users
7 | description: User-related operations
8 | - name: Jobs
9 | description: Job-related operations
10 | paths:
11 | /users:
12 | post:
13 | tags:
14 | - Users
15 | summary: Register User
16 | operationId: registerUser
17 | responses:
18 | '201':
19 | description: Created
20 | headers:
21 | Location:
22 | schema:
23 | type: string
24 | requestBody:
25 | content:
26 | application/json:
27 | schema:
28 | $ref: '#/components/schemas/User'
29 | security: []
30 | /users/{id}:
31 | parameters:
32 | - schema:
33 | type: string
34 | name: id
35 | in: path
36 | required: true
37 | get:
38 | tags:
39 | - Users
40 | summary: View User
41 | operationId: viewUserWithId
42 | responses:
43 | '200':
44 | description: OK
45 | content:
46 | application/json:
47 | schema:
48 | $ref: '#/components/schemas/User'
49 | put:
50 | tags:
51 | - Users
52 | summary: Modify User
53 | operationId: modifyUserWithId
54 | responses:
55 | '200':
56 | description: OK
57 | content:
58 | application/json:
59 | schema:
60 | $ref: '#/components/schemas/User'
61 | requestBody:
62 | content:
63 | application/json:
64 | schema:
65 | $ref: '#/components/schemas/User'
66 | delete:
67 | tags:
68 | - Users
69 | summary: Delete User
70 | operationId: deleteUserWithId
71 | responses:
72 | '204':
73 | description: No Content
74 | /jobs:
75 | post:
76 | tags:
77 | - Jobs
78 | summary: Create Job
79 | operationId: createJob
80 | responses:
81 | '201':
82 | description: Created
83 | headers:
84 | Location:
85 | schema:
86 | type: string
87 | requestBody:
88 | content:
89 | application/json:
90 | schema:
91 | $ref: '#/components/schemas/Job'
92 | get:
93 | tags:
94 | - Jobs
95 | summary: List/Search Available Jobs
96 | operationId: listOrSearchAvailableJobs
97 | parameters:
98 | - name: start_time_before
99 | in: query
100 | description: Search jobs starting before this date and time.
101 | schema:
102 | type: string
103 | format: date-time
104 | - name: start_time_after
105 | in: query
106 | description: Search jobs starting after this date and time.
107 | schema:
108 | type: string
109 | format: date-time
110 | - name: end_time_before
111 | in: query
112 | description: Search jobs ending before this date and time.
113 | schema:
114 | type: string
115 | format: date-time
116 | - name: end_time_after
117 | in: query
118 | description: Search jobs ending after this date and time.
119 | schema:
120 | type: string
121 | format: date-time
122 | - name: activity
123 | in: query
124 | description: Performs a full-text search for the phrase entered in job activities.
125 | schema:
126 | type: string
127 | - name: pets
128 | in: query
129 | description: Searches for pets matching specific criteria.
130 | style: deepObject
131 | schema:
132 | type: object
133 | properties:
134 | age_below:
135 | type: integer
136 | description: Return only pets with this age or younger.
137 | age_above:
138 | type: integer
139 | description: Return only pets with this age or older.
140 | species:
141 | type: string
142 | description: Return only pets with this species. Provide multiple species as comma-separated values.
143 | - name: limit
144 | in: query
145 | description: The maximum number of results to return.
146 | schema:
147 | type: integer
148 | default: 20
149 | maximum: 100
150 | - name: cursor
151 | in: query
152 | description: Use the cursor from the response to access more results.
153 | schema:
154 | type: string
155 | - name: sort
156 | in: query
157 | description: |
158 | Indicate the sorting key and direction for the results.
159 | Use the field name, suffixed with ":asc" for ascending
160 | or ":desc" for descending order.
161 | Valid fields: start_time, end_time
162 | schema:
163 | type: string
164 | responses:
165 | '200':
166 | description: OK
167 | content:
168 | application/json:
169 | schema:
170 | type: object
171 | properties:
172 | items:
173 | type: array
174 | items:
175 | $ref: '#/components/schemas/Job'
176 | cursor:
177 | type: string
178 | description: Cursor for the next result page.
179 | nullable: true
180 | /jobs/{id}:
181 | parameters:
182 | - schema:
183 | type: string
184 | name: id
185 | in: path
186 | required: true
187 | get:
188 | tags:
189 | - Jobs
190 | summary: View Job
191 | operationId: viewJobWithId
192 | responses:
193 | '200':
194 | description: OK
195 | content:
196 | application/json:
197 | schema:
198 | $ref: '#/components/schemas/Job'
199 | put:
200 | tags:
201 | - Jobs
202 | summary: Modify Job
203 | operationId: modifyJobWithId
204 | responses:
205 | '200':
206 | description: OK
207 | content:
208 | application/json:
209 | schema:
210 | $ref: '#/components/schemas/Job'
211 | requestBody:
212 | content:
213 | application/json:
214 | schema:
215 | $ref: '#/components/schemas/Job'
216 | delete:
217 | tags:
218 | - Jobs
219 | summary: Delete Job
220 | operationId: deleteJobWithId
221 | responses:
222 | '204':
223 | description: No Content
224 | /jobs/{id}/job-applications:
225 | parameters:
226 | - schema:
227 | type: string
228 | name: id
229 | in: path
230 | required: true
231 | get:
232 | tags:
233 | - Jobs
234 | summary: List Applications For Job
235 | operationId: viewApplicationsForJob
236 | responses:
237 | '200':
238 | description: OK
239 | content:
240 | application/json:
241 | schema:
242 | type: object
243 | properties:
244 | items:
245 | type: array
246 | items:
247 | $ref: '#/components/schemas/JobApplication'
248 | post:
249 | tags:
250 | - Jobs
251 | summary: Create Job Application
252 | operationId: createJobApplication
253 | responses:
254 | '201':
255 | description: Created
256 | headers:
257 | Location:
258 | schema:
259 | type: string
260 | requestBody:
261 | content:
262 | application/json:
263 | schema:
264 | $ref: '#/components/schemas/JobApplication'
265 | /users/{id}/jobs:
266 | parameters:
267 | - schema:
268 | type: string
269 | name: id
270 | in: path
271 | required: true
272 | get:
273 | tags:
274 | - Users
275 | summary: List Jobs For User
276 | operationId: listJobsForUser
277 | responses:
278 | '200':
279 | description: OK
280 | content:
281 | application/json:
282 | schema:
283 | type: object
284 | properties:
285 | items:
286 | type: array
287 | items:
288 | $ref: '#/components/schemas/Job'
289 | /users/{id}/job-applications:
290 | parameters:
291 | - name: id
292 | in: path
293 | required: true
294 | schema:
295 | type: integer
296 | get:
297 | tags:
298 | - Users
299 | summary: List Applications For User
300 | operationId: viewApplicationsForUser
301 | responses:
302 | '200':
303 | description: OK
304 | content:
305 | application/json:
306 | schema:
307 | type: object
308 | properties:
309 | items:
310 | type: array
311 | items:
312 | $ref: '#/components/schemas/JobApplication'
313 | /job-applications/{id}:
314 | parameters:
315 | - schema:
316 | type: string
317 | name: id
318 | in: path
319 | required: true
320 | put:
321 | tags:
322 | - Jobs
323 | summary: Modify Job Application
324 | operationId: modifyJobApplicationWithId
325 | requestBody:
326 | description: Update the application details
327 | content:
328 | application/json:
329 | schema:
330 | $ref: '#/components/schemas/JobApplication'
331 | responses:
332 | '200':
333 | description: OK
334 | content:
335 | application/json:
336 | schema:
337 | type: array
338 | items:
339 | $ref: '#/components/schemas/JobApplication'
340 | /sessions:
341 | post:
342 | tags:
343 | - Users
344 | summary: Start Session (Login)
345 | operationId: startSession
346 | responses:
347 | '200':
348 | description: OK
349 | content:
350 | application/json:
351 | schema:
352 | $ref: '#/components/schemas/Session'
353 | requestBody:
354 | content:
355 | application/json:
356 | schema:
357 | type: object
358 | properties:
359 | email:
360 | type: string
361 | password:
362 | type: string
363 | security: []
364 | components:
365 | schemas:
366 | User:
367 | type: object
368 | properties:
369 | id:
370 | type: string
371 | email:
372 | type: string
373 | password:
374 | type: string
375 | full_name:
376 | type: string
377 | roles:
378 | type: array
379 | items:
380 | type: string
381 | Job:
382 | type: object
383 | properties:
384 | id:
385 | type: string
386 | creator_user_id:
387 | type: string
388 | start_time:
389 | type: string
390 | end_time:
391 | type: string
392 | activity:
393 | type: string
394 | pets:
395 | type: array
396 | items:
397 | $ref: '#/components/schemas/Pet'
398 | Dog:
399 | type: object
400 | properties:
401 | species:
402 | type: string
403 | breed:
404 | type: string
405 | size:
406 | type: string
407 | required:
408 | - species
409 | Cat:
410 | type: object
411 | properties:
412 | species:
413 | type: string
414 | breed:
415 | type: string
416 | required:
417 | - species
418 | Pet:
419 | allOf:
420 | - type: object
421 | properties:
422 | name:
423 | type: string
424 | age:
425 | type: integer
426 | - oneOf:
427 | - $ref: '#/components/schemas/Cat'
428 | - $ref: '#/components/schemas/Dog'
429 | discriminator:
430 | propertyName: species
431 | mapping:
432 | Cat: '#/components/schemas/Cat'
433 | Dog: '#/components/schemas/Dog'
434 | JobApplication:
435 | type: object
436 | properties:
437 | id:
438 | type: string
439 | status:
440 | type: string
441 | user_id:
442 | type: string
443 | job_id:
444 | type: string
445 | Session:
446 | type: object
447 | properties:
448 | user_id:
449 | type: string
450 | auth_header:
451 | type: string
452 | securitySchemes:
453 | SessionToken:
454 | type: apiKey
455 | in: header
456 | name: Authorization
457 | security:
458 | - SessionToken: []
459 |
--------------------------------------------------------------------------------
/ch18/README.md:
--------------------------------------------------------------------------------
1 | # Chapter 18: Supporting the unhappy path: error handling with problem+json
2 |
3 | The file [openapi.yaml](openapi.yaml) contains the OpenAPI file for the PetSitter project after the updates made in [chapter 18](https://livebook.manning.com/book/designing-apis-with-swagger-and-openapi/chapter-18).
--------------------------------------------------------------------------------
/ch18/openapi.yaml:
--------------------------------------------------------------------------------
1 | openapi: 3.0.0
2 | info:
3 | title: PetSitter API
4 | version: "0.1"
5 | tags:
6 | - name: Users
7 | description: User-related operations
8 | - name: Jobs
9 | description: Job-related operations
10 | paths:
11 | /users:
12 | post:
13 | tags:
14 | - Users
15 | summary: Register User
16 | operationId: registerUser
17 | responses:
18 | '201':
19 | description: Created
20 | headers:
21 | Location:
22 | schema:
23 | type: string
24 | requestBody:
25 | content:
26 | application/json:
27 | schema:
28 | $ref: '#/components/schemas/User'
29 | security: []
30 | /users/{id}:
31 | parameters:
32 | - schema:
33 | type: string
34 | name: id
35 | in: path
36 | required: true
37 | get:
38 | tags:
39 | - Users
40 | summary: View User
41 | operationId: viewUserWithId
42 | responses:
43 | '200':
44 | description: OK
45 | content:
46 | application/json:
47 | schema:
48 | $ref: '#/components/schemas/User'
49 | put:
50 | tags:
51 | - Users
52 | summary: Modify User
53 | operationId: modifyUserWithId
54 | responses:
55 | '200':
56 | description: OK
57 | content:
58 | application/json:
59 | schema:
60 | $ref: '#/components/schemas/User'
61 | requestBody:
62 | content:
63 | application/json:
64 | schema:
65 | $ref: '#/components/schemas/User'
66 | delete:
67 | tags:
68 | - Users
69 | summary: Delete User
70 | operationId: deleteUserWithId
71 | responses:
72 | '204':
73 | description: No Content
74 | /jobs:
75 | post:
76 | tags:
77 | - Jobs
78 | summary: Create Job
79 | operationId: createJob
80 | responses:
81 | '201':
82 | description: Created
83 | headers:
84 | Location:
85 | schema:
86 | type: string
87 | '400':
88 | description: Bad request
89 | content:
90 | application/json:
91 | schema:
92 | $ref: '#/components/schemas/OASError'
93 | '401':
94 | description: Unauthorized
95 | content:
96 | application/json:
97 | schema:
98 | $ref: '#/components/schemas/OASError'
99 | '403':
100 | description: Forbidden
101 | content:
102 | application/problem+json:
103 | schema:
104 | $ref: '#/components/schemas/Problem'
105 | get:
106 | tags:
107 | - Jobs
108 | summary: List/Search Available Jobs
109 | operationId: listOrSearchAvailableJobs
110 | parameters:
111 | - name: start_time_before
112 | in: query
113 | description: Search jobs starting before this date and time.
114 | schema:
115 | type: string
116 | format: date-time
117 | - name: start_time_after
118 | in: query
119 | description: Search jobs starting after this date and time.
120 | schema:
121 | type: string
122 | format: date-time
123 | - name: end_time_before
124 | in: query
125 | description: Search jobs ending before this date and time.
126 | schema:
127 | type: string
128 | format: date-time
129 | - name: end_time_after
130 | in: query
131 | description: Search jobs ending after this date and time.
132 | schema:
133 | type: string
134 | format: date-time
135 | - name: activity
136 | in: query
137 | description: Performs a full-text search for the phrase entered in job activities.
138 | schema:
139 | type: string
140 | - name: pets
141 | in: query
142 | description: Searches for pets matching specific criteria.
143 | style: deepObject
144 | schema:
145 | type: object
146 | properties:
147 | age_below:
148 | type: integer
149 | description: Return only pets with this age or younger.
150 | age_above:
151 | type: integer
152 | description: Return only pets with this age or older.
153 | species:
154 | type: string
155 | description: Return only pets with this species. Provide multiple species as comma-separated values.
156 | - name: limit
157 | in: query
158 | description: The maximum number of results to return.
159 | schema:
160 | type: integer
161 | default: 20
162 | maximum: 100
163 | - name: cursor
164 | in: query
165 | description: Use the cursor from the response to access more results.
166 | schema:
167 | type: string
168 | - name: sort
169 | in: query
170 | description: |
171 | Indicate the sorting key and direction for the results.
172 | Use the field name, suffixed with ":asc" for ascending
173 | or ":desc" for descending order.
174 | Valid fields: start_time, end_time
175 | schema:
176 | type: string
177 | responses:
178 | '200':
179 | description: OK
180 | content:
181 | application/json:
182 | schema:
183 | type: object
184 | properties:
185 | items:
186 | type: array
187 | items:
188 | $ref: '#/components/schemas/Job'
189 | cursor:
190 | type: string
191 | description: Cursor for the next result page.
192 | nullable: true
193 | /jobs/{id}:
194 | parameters:
195 | - schema:
196 | type: string
197 | name: id
198 | in: path
199 | required: true
200 | get:
201 | tags:
202 | - Jobs
203 | summary: View Job
204 | operationId: viewJobWithId
205 | responses:
206 | '200':
207 | description: OK
208 | content:
209 | application/json:
210 | schema:
211 | $ref: '#/components/schemas/Job'
212 | put:
213 | tags:
214 | - Jobs
215 | summary: Modify Job
216 | operationId: modifyJobWithId
217 | responses:
218 | '200':
219 | description: OK
220 | content:
221 | application/json:
222 | schema:
223 | $ref: '#/components/schemas/Job'
224 | requestBody:
225 | content:
226 | application/json:
227 | schema:
228 | $ref: '#/components/schemas/Job'
229 | delete:
230 | tags:
231 | - Jobs
232 | summary: Delete Job
233 | operationId: deleteJobWithId
234 | responses:
235 | '204':
236 | description: No Content
237 | /jobs/{id}/job-applications:
238 | parameters:
239 | - schema:
240 | type: string
241 | name: id
242 | in: path
243 | required: true
244 | get:
245 | tags:
246 | - Jobs
247 | summary: List Applications For Job
248 | operationId: viewApplicationsForJob
249 | responses:
250 | '200':
251 | description: OK
252 | content:
253 | application/json:
254 | schema:
255 | type: object
256 | properties:
257 | items:
258 | type: array
259 | items:
260 | $ref: '#/components/schemas/JobApplication'
261 | post:
262 | tags:
263 | - Jobs
264 | summary: Create Job Application
265 | operationId: createJobApplication
266 | responses:
267 | '201':
268 | description: Created
269 | headers:
270 | Location:
271 | schema:
272 | type: string
273 | requestBody:
274 | content:
275 | application/json:
276 | schema:
277 | $ref: '#/components/schemas/JobApplication'
278 | /users/{id}/jobs:
279 | parameters:
280 | - schema:
281 | type: string
282 | name: id
283 | in: path
284 | required: true
285 | get:
286 | tags:
287 | - Users
288 | summary: List Jobs For User
289 | operationId: listJobsForUser
290 | responses:
291 | '200':
292 | description: OK
293 | content:
294 | application/json:
295 | schema:
296 | type: object
297 | properties:
298 | items:
299 | type: array
300 | items:
301 | $ref: '#/components/schemas/Job'
302 | /users/{id}/job-applications:
303 | parameters:
304 | - name: id
305 | in: path
306 | required: true
307 | schema:
308 | type: integer
309 | get:
310 | tags:
311 | - Users
312 | summary: List Applications For User
313 | operationId: viewApplicationsForUser
314 | responses:
315 | '200':
316 | description: OK
317 | content:
318 | application/json:
319 | schema:
320 | type: object
321 | properties:
322 | items:
323 | type: array
324 | items:
325 | $ref: '#/components/schemas/JobApplication'
326 | /job-applications/{id}:
327 | parameters:
328 | - schema:
329 | type: string
330 | name: id
331 | in: path
332 | required: true
333 | put:
334 | tags:
335 | - Jobs
336 | summary: Modify Job Application
337 | operationId: modifyJobApplicationWithId
338 | requestBody:
339 | description: Update the application details
340 | content:
341 | application/json:
342 | schema:
343 | $ref: '#/components/schemas/JobApplication'
344 | responses:
345 | '200':
346 | description: OK
347 | content:
348 | application/json:
349 | schema:
350 | type: array
351 | items:
352 | $ref: '#/components/schemas/JobApplication'
353 | /sessions:
354 | post:
355 | tags:
356 | - Users
357 | summary: Start Session (Login)
358 | operationId: startSession
359 | responses:
360 | '200':
361 | description: OK
362 | content:
363 | application/json:
364 | schema:
365 | $ref: '#/components/schemas/Session'
366 | requestBody:
367 | content:
368 | application/json:
369 | schema:
370 | type: object
371 | properties:
372 | email:
373 | type: string
374 | password:
375 | type: string
376 | security: []
377 | components:
378 | schemas:
379 | User:
380 | type: object
381 | properties:
382 | id:
383 | type: string
384 | email:
385 | type: string
386 | password:
387 | type: string
388 | full_name:
389 | type: string
390 | roles:
391 | type: array
392 | items:
393 | type: string
394 | Job:
395 | type: object
396 | properties:
397 | id:
398 | type: string
399 | creator_user_id:
400 | type: string
401 | start_time:
402 | type: string
403 | end_time:
404 | type: string
405 | activity:
406 | type: string
407 | pets:
408 | type: array
409 | items:
410 | $ref: '#/components/schemas/Pet'
411 | Dog:
412 | type: object
413 | properties:
414 | species:
415 | type: string
416 | breed:
417 | type: string
418 | size:
419 | type: string
420 | required:
421 | - species
422 | Cat:
423 | type: object
424 | properties:
425 | species:
426 | type: string
427 | breed:
428 | type: string
429 | required:
430 | - species
431 | Pet:
432 | allOf:
433 | - type: object
434 | properties:
435 | name:
436 | type: string
437 | age:
438 | type: integer
439 | - oneOf:
440 | - $ref: '#/components/schemas/Cat'
441 | - $ref: '#/components/schemas/Dog'
442 | discriminator:
443 | propertyName: species
444 | mapping:
445 | Cat: '#/components/schemas/Cat'
446 | Dog: '#/components/schemas/Dog'
447 | JobApplication:
448 | type: object
449 | properties:
450 | id:
451 | type: string
452 | status:
453 | type: string
454 | user_id:
455 | type: string
456 | job_id:
457 | type: string
458 | Session:
459 | type: object
460 | properties:
461 | user_id:
462 | type: string
463 | auth_header:
464 | type: string
465 | OASError:
466 | type: object
467 | properties:
468 | message:
469 | type: string
470 | description: Human-readable error message
471 | errors:
472 | type: array
473 | items:
474 | type: object
475 | properties:
476 | path:
477 | type: string
478 | description: For input validation errors, identifies where in the JSON request body the error occured
479 | message:
480 | type: string
481 | description: Human-readable error message
482 | errorCode:
483 | type: string
484 | description: Code indicating error type
485 | Problem:
486 | type: object
487 | properties:
488 | type:
489 | type: string
490 | description: URI indicating error type
491 | title:
492 | type: string
493 | description: Human-readable error title
494 | status:
495 | type: integer
496 | description: HTTP status code
497 | detail:
498 | type: string
499 | description: Human-readable error details
500 | instance:
501 | type: string
502 | description: URI indicating error instance
503 | securitySchemes:
504 | SessionToken:
505 | type: apiKey
506 | in: header
507 | name: Authorization
508 | security:
509 | - SessionToken: []
510 |
--------------------------------------------------------------------------------
/ch19/README.md:
--------------------------------------------------------------------------------
1 | # Chapter 19: Improving input validation with advanced JSON Schema
2 |
3 | The file [openapi.yaml](openapi.yaml) contains the OpenAPI file for the PetSitter project after the updates made in [chapter 19](https://livebook.manning.com/book/designing-apis-with-swagger-and-openapi/chapter-19).
--------------------------------------------------------------------------------
/ch19/openapi.yaml:
--------------------------------------------------------------------------------
1 | openapi: 3.0.3
2 | info:
3 | title: PetSitter API
4 | version: "0.1"
5 | tags:
6 | - name: Users
7 | description: User-related operations
8 | - name: Jobs
9 | description: Job-related operations
10 | paths:
11 | /users:
12 | post:
13 | tags:
14 | - Users
15 | summary: Register User
16 | operationId: registerUser
17 | responses:
18 | '201':
19 | description: Created
20 | headers:
21 | Location:
22 | schema:
23 | type: string
24 | requestBody:
25 | content:
26 | application/json:
27 | schema:
28 | $ref: '#/components/schemas/User'
29 | security: []
30 | /users/{id}:
31 | parameters:
32 | - schema:
33 | type: string
34 | name: id
35 | in: path
36 | required: true
37 | get:
38 | tags:
39 | - Users
40 | summary: View User
41 | operationId: viewUserWithId
42 | responses:
43 | '200':
44 | description: OK
45 | content:
46 | application/json:
47 | schema:
48 | $ref: '#/components/schemas/User'
49 | put:
50 | tags:
51 | - Users
52 | summary: Modify User
53 | operationId: modifyUserWithId
54 | responses:
55 | '200':
56 | description: OK
57 | content:
58 | application/json:
59 | schema:
60 | $ref: '#/components/schemas/User'
61 | requestBody:
62 | content:
63 | application/json:
64 | schema:
65 | $ref: '#/components/schemas/User'
66 | delete:
67 | tags:
68 | - Users
69 | summary: Delete User
70 | operationId: deleteUserWithId
71 | responses:
72 | '204':
73 | description: No Content
74 | /jobs:
75 | post:
76 | tags:
77 | - Jobs
78 | summary: Create Job
79 | operationId: createJob
80 | responses:
81 | '201':
82 | description: Created
83 | headers:
84 | Location:
85 | schema:
86 | type: string
87 | '400':
88 | description: Bad request
89 | content:
90 | application/json:
91 | schema:
92 | $ref: '#/components/schemas/OASError'
93 | '401':
94 | description: Unauthorized
95 | content:
96 | application/json:
97 | schema:
98 | $ref: '#/components/schemas/OASError'
99 | '403':
100 | description: Forbidden
101 | content:
102 | application/problem+json:
103 | schema:
104 | $ref: '#/components/schemas/Problem'
105 | get:
106 | tags:
107 | - Jobs
108 | summary: List/Search Available Jobs
109 | operationId: listOrSearchAvailableJobs
110 | parameters:
111 | - name: start_time_before
112 | in: query
113 | description: Search jobs starting before this date and time.
114 | schema:
115 | type: string
116 | format: date-time
117 | - name: start_time_after
118 | in: query
119 | description: Search jobs starting after this date and time.
120 | schema:
121 | type: string
122 | format: date-time
123 | - name: end_time_before
124 | in: query
125 | description: Search jobs ending before this date and time.
126 | schema:
127 | type: string
128 | format: date-time
129 | - name: end_time_after
130 | in: query
131 | description: Search jobs ending after this date and time.
132 | schema:
133 | type: string
134 | format: date-time
135 | - name: activity
136 | in: query
137 | description: Performs a full-text search for the phrase entered in job activities.
138 | schema:
139 | type: string
140 | - name: pets
141 | in: query
142 | description: Searches for pets matching specific criteria.
143 | style: deepObject
144 | schema:
145 | type: object
146 | properties:
147 | age_below:
148 | type: integer
149 | description: Return only pets with this age or younger.
150 | age_above:
151 | type: integer
152 | description: Return only pets with this age or older.
153 | species:
154 | type: string
155 | description: Return only pets with this species. Provide multiple species as comma-separated values.
156 | - name: limit
157 | in: query
158 | description: The maximum number of results to return.
159 | schema:
160 | type: integer
161 | default: 20
162 | maximum: 100
163 | - name: cursor
164 | in: query
165 | description: Use the cursor from the response to access more results.
166 | schema:
167 | type: string
168 | - name: sort
169 | in: query
170 | description: |
171 | Indicate the sorting key and direction for the results.
172 | Use the field name, suffixed with ":asc" for ascending
173 | or ":desc" for descending order.
174 | Valid fields: start_time, end_time
175 | schema:
176 | type: string
177 | responses:
178 | '200':
179 | description: OK
180 | content:
181 | application/json:
182 | schema:
183 | type: object
184 | properties:
185 | items:
186 | type: array
187 | items:
188 | $ref: '#/components/schemas/Job'
189 | cursor:
190 | type: string
191 | description: Cursor for the next result page.
192 | nullable: true
193 | /jobs/{id}:
194 | parameters:
195 | - schema:
196 | type: string
197 | name: id
198 | in: path
199 | required: true
200 | get:
201 | tags:
202 | - Jobs
203 | summary: View Job
204 | operationId: viewJobWithId
205 | responses:
206 | '200':
207 | description: OK
208 | content:
209 | application/json:
210 | schema:
211 | $ref: '#/components/schemas/Job'
212 | put:
213 | tags:
214 | - Jobs
215 | summary: Modify Job
216 | operationId: modifyJobWithId
217 | responses:
218 | '200':
219 | description: OK
220 | content:
221 | application/json:
222 | schema:
223 | $ref: '#/components/schemas/Job'
224 | requestBody:
225 | content:
226 | application/json:
227 | schema:
228 | $ref: '#/components/schemas/Job'
229 | delete:
230 | tags:
231 | - Jobs
232 | summary: Delete Job
233 | operationId: deleteJobWithId
234 | responses:
235 | '204':
236 | description: No Content
237 | /jobs/{id}/job-applications:
238 | parameters:
239 | - schema:
240 | type: string
241 | name: id
242 | in: path
243 | required: true
244 | get:
245 | tags:
246 | - Jobs
247 | summary: List Applications For Job
248 | operationId: viewApplicationsForJob
249 | responses:
250 | '200':
251 | description: OK
252 | content:
253 | application/json:
254 | schema:
255 | type: object
256 | properties:
257 | items:
258 | type: array
259 | items:
260 | $ref: '#/components/schemas/JobApplication'
261 | post:
262 | tags:
263 | - Jobs
264 | summary: Create Job Application
265 | operationId: createJobApplication
266 | responses:
267 | '201':
268 | description: Created
269 | headers:
270 | Location:
271 | schema:
272 | type: string
273 | requestBody:
274 | content:
275 | application/json:
276 | schema:
277 | $ref: '#/components/schemas/JobApplication'
278 | /users/{id}/jobs:
279 | parameters:
280 | - schema:
281 | type: string
282 | name: id
283 | in: path
284 | required: true
285 | get:
286 | tags:
287 | - Users
288 | summary: List Jobs For User
289 | operationId: listJobsForUser
290 | responses:
291 | '200':
292 | description: OK
293 | content:
294 | application/json:
295 | schema:
296 | type: object
297 | properties:
298 | items:
299 | type: array
300 | items:
301 | $ref: '#/components/schemas/Job'
302 | /users/{id}/job-applications:
303 | parameters:
304 | - name: id
305 | in: path
306 | required: true
307 | schema:
308 | type: integer
309 | get:
310 | tags:
311 | - Users
312 | summary: List Applications For User
313 | operationId: viewApplicationsForUser
314 | responses:
315 | '200':
316 | description: OK
317 | content:
318 | application/json:
319 | schema:
320 | type: object
321 | properties:
322 | items:
323 | type: array
324 | items:
325 | $ref: '#/components/schemas/JobApplication'
326 | /job-applications/{id}:
327 | parameters:
328 | - schema:
329 | type: string
330 | name: id
331 | in: path
332 | required: true
333 | put:
334 | tags:
335 | - Jobs
336 | summary: Modify Job Application
337 | operationId: modifyJobApplicationWithId
338 | requestBody:
339 | description: Update the application details
340 | content:
341 | application/json:
342 | schema:
343 | $ref: '#/components/schemas/JobApplication'
344 | responses:
345 | '200':
346 | description: OK
347 | content:
348 | application/json:
349 | schema:
350 | type: array
351 | items:
352 | $ref: '#/components/schemas/JobApplication'
353 | /sessions:
354 | post:
355 | tags:
356 | - Users
357 | summary: Start Session (Login)
358 | operationId: startSession
359 | responses:
360 | '200':
361 | description: OK
362 | content:
363 | application/json:
364 | schema:
365 | $ref: '#/components/schemas/Session'
366 | requestBody:
367 | content:
368 | application/json:
369 | schema:
370 | type: object
371 | properties:
372 | email:
373 | type: string
374 | password:
375 | type: string
376 | security: []
377 | components:
378 | schemas:
379 | User:
380 | type: object
381 | properties:
382 | id:
383 | type: integer
384 | readOnly: true
385 | email:
386 | type: string
387 | format: email
388 | password:
389 | type: string
390 | format: password
391 | writeOnly: true
392 | minLength: 8
393 | full_name:
394 | type: string
395 | minLength: 2
396 | maxLength: 50
397 | roles:
398 | type: array
399 | minItems: 1
400 | uniqueItems: true
401 | items:
402 | type: string
403 | enum:
404 | - PetOwner
405 | - PetSitter
406 | - Admin
407 | required:
408 | - email
409 | - full_name
410 | - roles
411 | Job:
412 | type: object
413 | properties:
414 | id:
415 | type: integer
416 | readOnly: true
417 | creator_user_id:
418 | type: integer
419 | readOnly: true
420 | start_time:
421 | type: string
422 | format: date-time
423 | end_time:
424 | type: string
425 | format: date-time
426 | activity:
427 | type: string
428 | minLength: 5
429 | maxLength: 500
430 | pets:
431 | type: array
432 | minItems: 1
433 | maxItems: 10
434 | items:
435 | $ref: '#/components/schemas/Pet'
436 | required:
437 | - id
438 | - creator_user_id
439 | - start_time
440 | - end_time
441 | - pets
442 | Dog:
443 | type: object
444 | properties:
445 | species:
446 | type: string
447 | breed:
448 | type: string
449 | size:
450 | type: string
451 | required:
452 | - species
453 | Cat:
454 | type: object
455 | properties:
456 | species:
457 | type: string
458 | breed:
459 | type: string
460 | required:
461 | - species
462 | Pet:
463 | allOf:
464 | - type: object
465 | properties:
466 | name:
467 | type: string
468 | minLength: 2
469 | maxLength: 20
470 | age:
471 | type: integer
472 | minimum: 1
473 | maximum: 100
474 | - oneOf:
475 | - $ref: '#/components/schemas/Cat'
476 | - $ref: '#/components/schemas/Dog'
477 | discriminator:
478 | propertyName: species
479 | mapping:
480 | Cat: '#/components/schemas/Cat'
481 | Dog: '#/components/schemas/Dog'
482 | JobApplication:
483 | type: object
484 | properties:
485 | id:
486 | type: string
487 | readOnly: true
488 | status:
489 | type: string
490 | default: applying
491 | enum:
492 | - applying
493 | - approved
494 | - rejected
495 | user_id:
496 | type: string
497 | readOnly: true
498 | job_id:
499 | type: string
500 | readOnly: true
501 | required:
502 | - id
503 | - status
504 | - user_id
505 | - job_id
506 | Session:
507 | type: object
508 | properties:
509 | user_id:
510 | type: string
511 | auth_header:
512 | type: string
513 | OASError:
514 | type: object
515 | properties:
516 | message:
517 | type: string
518 | description: Human-readable error message
519 | errors:
520 | type: array
521 | items:
522 | type: object
523 | properties:
524 | path:
525 | type: string
526 | description: For input validation errors, identifies where in the JSON request body the error occured
527 | message:
528 | type: string
529 | description: Human-readable error message
530 | errorCode:
531 | type: string
532 | description: Code indicating error type
533 | Problem:
534 | type: object
535 | properties:
536 | type:
537 | type: string
538 | description: URI indicating error type
539 | title:
540 | type: string
541 | description: Human-readable error title
542 | status:
543 | type: integer
544 | description: HTTP status code
545 | detail:
546 | type: string
547 | description: Human-readable error details
548 | instance:
549 | type: string
550 | description: URI indicating error instance
551 | securitySchemes:
552 | SessionToken:
553 | type: apiKey
554 | in: header
555 | name: Authorization
556 | security:
557 | - SessionToken: []
558 |
--------------------------------------------------------------------------------
/ch20/README.md:
--------------------------------------------------------------------------------
1 | # Chapter 20: Versioning an API and handling breaking changes
2 |
3 | The file [openapi.yaml](openapi.yaml) contains the OpenAPI file for the PetSitter project after the updates made in [chapter 20](https://livebook.manning.com/book/designing-apis-with-swagger-and-openapi/chapter-20).
--------------------------------------------------------------------------------
/ch20/openapi.yml:
--------------------------------------------------------------------------------
1 | openapi: 3.0.3
2 | info:
3 | title: PetSitter API
4 | version: "0.1"
5 | tags:
6 | - name: Users
7 | description: User-related operations
8 | - name: Jobs
9 | description: Job-related operations
10 | paths:
11 | /users:
12 | post:
13 | tags:
14 | - Users
15 | summary: Register User
16 | operationId: registerUser
17 | responses:
18 | '201':
19 | description: Created
20 | headers:
21 | Location:
22 | schema:
23 | type: string
24 | requestBody:
25 | content:
26 | application/json:
27 | schema:
28 | $ref: '#/components/schemas/User'
29 | security: []
30 | /users/{id}:
31 | parameters:
32 | - schema:
33 | type: string
34 | name: id
35 | in: path
36 | required: true
37 | get:
38 | tags:
39 | - Users
40 | summary: View User
41 | operationId: viewUserWithId
42 | responses:
43 | '200':
44 | description: OK
45 | content:
46 | application/json:
47 | schema:
48 | $ref: '#/components/schemas/User'
49 | put:
50 | tags:
51 | - Users
52 | summary: Modify User
53 | operationId: modifyUserWithId
54 | responses:
55 | '200':
56 | description: OK
57 | content:
58 | application/json:
59 | schema:
60 | $ref: '#/components/schemas/User'
61 | requestBody:
62 | content:
63 | application/json:
64 | schema:
65 | $ref: '#/components/schemas/User'
66 | delete:
67 | tags:
68 | - Users
69 | summary: Delete User
70 | operationId: deleteUserWithId
71 | responses:
72 | '204':
73 | description: No Content
74 | /jobs:
75 | post:
76 | tags:
77 | - Jobs
78 | summary: Create Job
79 | operationId: createJob
80 | responses:
81 | '201':
82 | description: Created
83 | headers:
84 | Location:
85 | schema:
86 | type: string
87 | '400':
88 | description: Bad request
89 | content:
90 | application/json:
91 | schema:
92 | $ref: '#/components/schemas/OASError'
93 | '401':
94 | description: Unauthorized
95 | content:
96 | application/json:
97 | schema:
98 | $ref: '#/components/schemas/OASError'
99 | '403':
100 | description: Forbidden
101 | content:
102 | application/problem+json:
103 | schema:
104 | $ref: '#/components/schemas/Problem'
105 | get:
106 | tags:
107 | - Jobs
108 | summary: List/Search Available Jobs
109 | operationId: listOrSearchAvailableJobs
110 | parameters:
111 | - name: start_time_before
112 | in: query
113 | description: Search jobs starting before this date and time.
114 | schema:
115 | type: string
116 | format: date-time
117 | - name: start_time_after
118 | in: query
119 | description: Search jobs starting after this date and time.
120 | schema:
121 | type: string
122 | format: date-time
123 | - name: end_time_before
124 | in: query
125 | description: Search jobs ending before this date and time.
126 | schema:
127 | type: string
128 | format: date-time
129 | - name: end_time_after
130 | in: query
131 | description: Search jobs ending after this date and time.
132 | schema:
133 | type: string
134 | format: date-time
135 | - name: activity
136 | in: query
137 | description: Performs a full-text search for the phrase entered in job activities.
138 | schema:
139 | type: string
140 | - name: pets
141 | in: query
142 | description: Searches for pets matching specific criteria.
143 | style: deepObject
144 | schema:
145 | type: object
146 | properties:
147 | age_below:
148 | type: integer
149 | description: Return only pets with this age or younger.
150 | age_above:
151 | type: integer
152 | description: Return only pets with this age or older.
153 | species:
154 | type: string
155 | description: Return only pets with this species. Provide multiple species as comma-separated values.
156 | - name: limit
157 | in: query
158 | description: The maximum number of results to return.
159 | schema:
160 | type: integer
161 | default: 20
162 | maximum: 100
163 | - name: cursor
164 | in: query
165 | description: Use the cursor from the response to access more results.
166 | schema:
167 | type: string
168 | - name: sort
169 | in: query
170 | description: |
171 | Indicate the sorting key and direction for the results.
172 | Use the field name, suffixed with ":asc" for ascending
173 | or ":desc" for descending order.
174 | Valid fields: start_time, end_time
175 | schema:
176 | type: string
177 | responses:
178 | '200':
179 | description: OK
180 | content:
181 | application/json:
182 | schema:
183 | type: object
184 | properties:
185 | items:
186 | type: array
187 | items:
188 | $ref: '#/components/schemas/Job'
189 | cursor:
190 | type: string
191 | description: Cursor for the next result page.
192 | nullable: true
193 | /jobs/{id}:
194 | parameters:
195 | - schema:
196 | type: string
197 | name: id
198 | in: path
199 | required: true
200 | get:
201 | tags:
202 | - Jobs
203 | summary: View Job
204 | operationId: viewJobWithId
205 | responses:
206 | '200':
207 | description: OK
208 | content:
209 | application/json:
210 | schema:
211 | $ref: '#/components/schemas/Job'
212 | put:
213 | tags:
214 | - Jobs
215 | summary: Modify Job
216 | operationId: modifyJobWithId
217 | responses:
218 | '200':
219 | description: OK
220 | content:
221 | application/json:
222 | schema:
223 | $ref: '#/components/schemas/Job'
224 | requestBody:
225 | content:
226 | application/json:
227 | schema:
228 | $ref: '#/components/schemas/Job'
229 | delete:
230 | tags:
231 | - Jobs
232 | summary: Delete Job
233 | operationId: deleteJobWithId
234 | responses:
235 | '204':
236 | description: No Content
237 | /jobs/{id}/job-applications:
238 | parameters:
239 | - schema:
240 | type: string
241 | name: id
242 | in: path
243 | required: true
244 | get:
245 | tags:
246 | - Jobs
247 | summary: List Applications For Job
248 | operationId: viewApplicationsForJob
249 | responses:
250 | '200':
251 | description: OK
252 | content:
253 | application/json:
254 | schema:
255 | type: object
256 | properties:
257 | items:
258 | type: array
259 | items:
260 | $ref: '#/components/schemas/JobApplication'
261 | post:
262 | tags:
263 | - Jobs
264 | summary: Create Job Application
265 | operationId: createJobApplication
266 | responses:
267 | '201':
268 | description: Created
269 | headers:
270 | Location:
271 | schema:
272 | type: string
273 | requestBody:
274 | content:
275 | application/json:
276 | schema:
277 | $ref: '#/components/schemas/JobApplication'
278 | /users/{id}/jobs:
279 | parameters:
280 | - schema:
281 | type: string
282 | name: id
283 | in: path
284 | required: true
285 | get:
286 | tags:
287 | - Users
288 | summary: List Jobs For User
289 | operationId: listJobsForUser
290 | responses:
291 | '200':
292 | description: OK
293 | content:
294 | application/json:
295 | schema:
296 | type: object
297 | properties:
298 | items:
299 | type: array
300 | items:
301 | $ref: '#/components/schemas/Job'
302 | /users/{id}/job-applications:
303 | parameters:
304 | - name: id
305 | in: path
306 | required: true
307 | schema:
308 | type: integer
309 | get:
310 | tags:
311 | - Users
312 | summary: List Applications For User
313 | operationId: viewApplicationsForUser
314 | responses:
315 | '200':
316 | description: OK
317 | content:
318 | application/json:
319 | schema:
320 | type: object
321 | properties:
322 | items:
323 | type: array
324 | items:
325 | $ref: '#/components/schemas/JobApplication'
326 | /job-applications/{id}:
327 | parameters:
328 | - schema:
329 | type: string
330 | name: id
331 | in: path
332 | required: true
333 | put:
334 | tags:
335 | - Jobs
336 | summary: Modify Job Application
337 | operationId: modifyJobApplicationWithId
338 | requestBody:
339 | description: Update the application details
340 | content:
341 | application/json:
342 | schema:
343 | $ref: '#/components/schemas/JobApplication'
344 | responses:
345 | '200':
346 | description: OK
347 | content:
348 | application/json:
349 | schema:
350 | type: array
351 | items:
352 | $ref: '#/components/schemas/JobApplication'
353 | /sessions:
354 | post:
355 | tags:
356 | - Users
357 | summary: Start Session (Login)
358 | operationId: startSession
359 | responses:
360 | '200':
361 | description: OK
362 | content:
363 | application/json:
364 | schema:
365 | $ref: '#/components/schemas/Session'
366 | requestBody:
367 | content:
368 | application/json:
369 | schema:
370 | type: object
371 | properties:
372 | email:
373 | type: string
374 | password:
375 | type: string
376 | security: []
377 | components:
378 | schemas:
379 | User:
380 | type: object
381 | properties:
382 | id:
383 | type: integer
384 | readOnly: true
385 | email:
386 | type: string
387 | format: email
388 | password:
389 | type: string
390 | format: password
391 | writeOnly: true
392 | minLength: 8
393 | full_name:
394 | type: string
395 | minLength: 2
396 | maxLength: 50
397 | roles:
398 | type: array
399 | minItems: 1
400 | uniqueItems: true
401 | items:
402 | type: string
403 | enum:
404 | - PetOwner
405 | - PetSitter
406 | - Admin
407 | required:
408 | - email
409 | - full_name
410 | - roles
411 | Job:
412 | type: object
413 | properties:
414 | id:
415 | type: integer
416 | readOnly: true
417 | creator_user_id:
418 | type: integer
419 | readOnly: true
420 | start_time:
421 | type: string
422 | format: date-time
423 | end_time:
424 | type: string
425 | format: date-time
426 | activity:
427 | type: string
428 | minLength: 5
429 | maxLength: 500
430 | dog:
431 | allOf:
432 | - $ref: '#/components/schemas/Dog'
433 | - description: |
434 | This is deprecated, prefer to use `pets`.
435 | If both exist, `dog` will be ignored and `pets` will be used.
436 | deprecated: true
437 | pets:
438 | type: array
439 | minItems: 1
440 | maxItems: 10
441 | items:
442 | $ref: '#/components/schemas/Pet'
443 | Dog:
444 | type: object
445 | properties:
446 | species:
447 | type: string
448 | breed:
449 | type: string
450 | size:
451 | type: string
452 | required:
453 | - species
454 | Cat:
455 | type: object
456 | properties:
457 | species:
458 | type: string
459 | breed:
460 | type: string
461 | required:
462 | - species
463 | Pet:
464 | allOf:
465 | - type: object
466 | properties:
467 | name:
468 | type: string
469 | minLength: 2
470 | maxLength: 20
471 | age:
472 | type: integer
473 | minimum: 1
474 | maximum: 100
475 | - oneOf:
476 | - $ref: '#/components/schemas/Cat'
477 | - $ref: '#/components/schemas/Dog'
478 | discriminator:
479 | propertyName: species
480 | mapping:
481 | Cat: '#/components/schemas/Cat'
482 | Dog: '#/components/schemas/Dog'
483 | JobApplication:
484 | type: object
485 | properties:
486 | id:
487 | type: string
488 | readOnly: true
489 | status:
490 | type: string
491 | default: applying
492 | enum:
493 | - applying
494 | - approved
495 | - rejected
496 | user_id:
497 | type: string
498 | readOnly: true
499 | job_id:
500 | type: string
501 | readOnly: true
502 | Session:
503 | type: object
504 | properties:
505 | user_id:
506 | type: string
507 | auth_header:
508 | type: string
509 | OASError:
510 | type: object
511 | properties:
512 | message:
513 | type: string
514 | description: Human-readable error message
515 | errors:
516 | type: array
517 | items:
518 | type: object
519 | properties:
520 | path:
521 | type: string
522 | description: For input validation errors, identifies where in the JSON request body the error occured
523 | message:
524 | type: string
525 | description: Human-readable error message
526 | errorCode:
527 | type: string
528 | description: Code indicating error type
529 | Problem:
530 | type: object
531 | properties:
532 | type:
533 | type: string
534 | description: URI indicating error type
535 | title:
536 | type: string
537 | description: Human-readable error title
538 | status:
539 | type: integer
540 | description: HTTP status code
541 | detail:
542 | type: string
543 | description: Human-readable error details
544 | instance:
545 | type: string
546 | description: URI indicating error instance
547 | securitySchemes:
548 | SessionToken:
549 | type: apiKey
550 | in: header
551 | name: Authorization
552 | security:
553 | - SessionToken: []
554 |
--------------------------------------------------------------------------------
/core-concept/openapi.yml:
--------------------------------------------------------------------------------
1 | openapi: 3.0.3
2 | info:
3 | title: UserAccount API
4 | description: For users
5 | version: 1.0.0
6 | tags:
7 | - name: User
8 | description: User related operations
9 | servers:
10 | - url: https://example.com
11 | paths:
12 | /users/{id}:
13 | put:
14 | summary: Modify user
15 | description: |
16 | Modify the user and return `updated_at`.
17 |
18 | Needs **Authentication**!
19 | operationId: modifyUser
20 | tags:
21 | - User
22 | security:
23 | - MyToken: []
24 | parameters:
25 | - name: id
26 | in: path
27 | required: true
28 | schema:
29 | type: string
30 | - name: role
31 | in: query
32 | schema:
33 | type: string
34 | enum:
35 | - admin
36 | - member
37 | default: member
38 |
39 | requestBody:
40 | content:
41 | application/json:
42 | schema:
43 | oneOf:
44 | - $ref: '#/components/schemas/Employee'
45 | - $ref: '#/components/schemas/Customer'
46 | responses:
47 | '200':
48 | description: Updated user
49 | content:
50 | application/json:
51 | schema:
52 | $ref: '#/components/schemas/User'
53 | '403':
54 | description: Forbidden
55 | content:
56 | application/problem+json:
57 | schema:
58 | $ref: '#/components/schemas/Error'
59 | components:
60 | securitySchemes:
61 | MyToken:
62 | type: apiKey
63 | in: header
64 | name: Authorization
65 | schemas:
66 | User:
67 | type: object
68 | required: [id, name]
69 | properties:
70 | id:
71 | type: string
72 | readOnly: true
73 | name:
74 | type: string
75 | password:
76 | type: string
77 | format: password
78 | writeOnly: true
79 | Employee:
80 | allOf:
81 | - $ref: '#/components/schemas/User'
82 | - type: object
83 | required:
84 | - employee_id
85 | properties:
86 | employee_id:
87 | type: string
88 | Customer:
89 | allOf:
90 | - $ref: '#/components/schemas/User'
91 | - type: object
92 | properties:
93 | sales_rep_id:
94 | type: string
95 | Error:
96 | type: object
97 | properties:
98 | title:
99 | type: string
100 | description: Error title
101 |
--------------------------------------------------------------------------------