1 |
|
2 |
|
3 | ## Anatomy of a path
|
4 |
|
5 | This topic looks at how paths are constructed and wired to response objects in a Swagger project's Swagger configuration file.
|
6 |
|
7 | * [Simple path example](#simple)
|
8 | * [More about route handling](#more)
|
9 | * [Request and response models](#models)
|
10 | * [Next steps](#nextstep)
|
11 |
|
12 | ### <a name="simple"></a>Simple path example
|
13 |
|
14 | The `/hello` path in the original Quick Start example looks like this:
|
15 |
|
16 | ```yaml
|
17 | paths:
|
18 | /hello:
|
19 | # binds swagger app logic to a route
|
20 | x-swagger-router-controller: hello_world
|
21 | get:
|
22 | description: Returns 'Hello' to the caller
|
23 | # used as the method name of the controller
|
24 | operationId: hello
|
25 | parameters:
|
26 | - name: name
|
27 | in: query
|
28 | description: The name of the person to whom to say hello
|
29 | required: false
|
30 | type: string
|
31 | responses:
|
32 | "200":
|
33 | description: Success
|
34 | schema:
|
35 | # a pointer to a definition
|
36 | $ref: #/definitions/HelloWorldResponse
|
37 | # responses may fall through to errors
|
38 | default:
|
39 | description: Error
|
40 | schema:
|
41 | $ref: "#/definitions/ErrorResponse"
|
42 | ```
|
43 |
|
44 | The parts of the path definition include:
|
45 |
|
46 | * `x-swagger-router-controller` is a custom Swagger extension to the Swagger model that maps a path to a controller file. For instance, `/weather` gets mapped to `api/controller/weather.js`. See [More about route handling]() below.
|
47 |
|
48 | * `operationId` maps to a method name in the controller file.
|
49 |
|
50 | * `security:` can be used to apply security schemes such as OAuth, Basic authentication, and API keys.
|
51 |
|
52 | * `parameters:` specifies any parameters used by the path. They can be passed as query or form parameters, or headers.
|
53 |
|
54 | * The other keys conform to the Swagger 2.0 [specifications](https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md). The parameters is a YAML array that defines all the parameters required for the call. The responses object defines the response specifications for response codes.
|
55 |
|
56 | ### <a name="more"></a>More about route handling
|
57 |
|
58 | As noted previously, `the x-swagger-router-controller` maps a path to a controller file. You can specify a router handler either at the path level or operation level in the Swagger file. For example, at the path level, like this:
|
59 |
|
60 | ```yaml
|
61 | paths:
|
62 | /hello:
|
63 | x-swagger-router-controller: hello_world
|
64 | get:
|
65 | description: Returns 'Hello' to the caller
|
66 | # used as the method name of the controller
|
67 | operationId: hello
|
68 | ```
|
69 |
|
70 | or at the operation level, like this:
|
71 |
|
72 | ```yaml
|
73 | paths:
|
74 | /hello:
|
75 | get:
|
76 | x-swagger-router-controller: hello_world
|
77 | description: Returns 'Hello' to the caller
|
78 | # used as the method name of the controller
|
79 | operationId: hello
|
80 | ```
|
81 |
|
82 | Routers applied at the operation level override routers specified at the path level.
|
83 |
|
84 | When you call your API with a given path, like `GET /hello`, the middleware checks to make sure there is an operation (e.g., "get") defined for that path. If not, then a 405 code is returned. If the path does have a corresponding operation defined, then a 200 response is returned. If you are running in mock mode, you'll get back a mock response, otherwise, you'll get back whatever response is returned by the controller. If you hit a path that is not specified in the Swagger file at all, then that's a 404.
|
85 |
|
86 | When you call your API, the middleware attempts to match a route defined in the Swagger file to a corresponding controller method. When you test your API, one of three possible results can occur:
|
87 |
|
88 | * A route defined in the Swagger file matches a controller file, and the controller has a method for the operation. In this case, either the route method is executed or, if you are in mock mode, a mock response is returned.
|
89 |
|
90 | * A route defined in the Swagger file matches a controller file, but there is no method in the controller for the operation. In this case, a 405 HTTP code is returned.
|
91 |
|
92 | * The requested route is not present in the Swagger file. In this case, a 404 code is returned.
|
93 |
|
94 | ### <a name="models"></a>Request and response models
|
95 |
|
96 | The Swagger specification allows you to define both request and the response models (also called schemas). The `path` definition described in the previous section is an example of a request model.
|
97 |
|
98 | Here's an example of a weather API that returns a relatively complex object.
|
99 |
|
100 | The Open Weather API returns an object that looks like the following:
|
101 |
|
102 | ```json
|
103 | {
|
104 | "coord": {
|
105 | "lon": -77.58,
|
106 | "lat": 35.27
|
107 | },
|
108 | "sys": {
|
109 | "type": 1,
|
110 | "id": 1786,
|
111 | "message": 0.1057,
|
112 | "country": "United States of America",
|
113 | "sunrise": 1409913972,
|
114 | "sunset": 1409959883
|
115 | },
|
116 | "weather": [
|
117 | {
|
118 | "id": 500,
|
119 | "main": "Rain",
|
120 | "description": "light rain",
|
121 | "icon": "10n"
|
122 | },
|
123 | {
|
124 | "id": 211,
|
125 | "main": "Thunderstorm",
|
126 | "description": "thunderstorm",
|
127 | "icon": "11n"
|
128 | }
|
129 | ],
|
130 | "base": "cmc stations",
|
131 | "main": {
|
132 | "temp": 78.58,
|
133 | "pressure": 1021,
|
134 | "humidity": 88,
|
135 | "temp_min": 73.4,
|
136 | "temp_max": 82.4
|
137 | },
|
138 | "wind": {
|
139 | "speed": 5.62,
|
140 | "deg": 40
|
141 | },
|
142 | "clouds": {
|
143 | "all": 90
|
144 | },
|
145 | "dt": 1409876198,
|
146 | "id": 4474436,
|
147 | "name": "Kinston",
|
148 | "cod": 200
|
149 | }
|
150 | ```
|
151 |
|
152 |
|
153 | To wire the path to the schema, you use the `responses` element to refer to the schema definition. In this example, we specify two responses, a 200 and an Error response. Note that you use `$ref` syntax to refer to each specific schema definition, listed in the `#/definitions` section (which we describe below).
|
154 |
|
155 | >Note: You must use explicit references of the form $ref: #/definitions/<DefName>. For example: $ref: #/definitions/WeatherResponse.
|
156 |
|
157 | >Note: In this case, all other responses that are not 200 will be referred to the Error response schema.
|
158 |
|
159 | ```yaml
|
160 | paths:
|
161 | /weather:
|
162 | ...
|
163 | responses:
|
164 | "200":
|
165 | description: Success
|
166 | schema:
|
167 | $ref: #/definitions/WeatherResponse
|
168 | default:
|
169 | description: Error
|
170 | schema:
|
171 | $ref: #/definitions/ErrorResponse
|
172 | ```
|
173 |
|
174 | Then in the `#/definitions` section of the Swagger document we define the `WeatherResponse` schemas that we referenced from the `/paths` section. Here is the schema that represents the JSON returned by the weather API (shown previously). These schemas are primarily used to provide response objects for mock mode:
|
175 |
|
176 | ```yaml
|
177 | definitions:
|
178 | WeatherResponse:
|
179 | type: "object"
|
180 | properties:
|
181 | base:
|
182 | type: "string"
|
183 | clouds:
|
184 | type: "object"
|
185 | properties:
|
186 | all:
|
187 | type: "number"
|
188 | cod:
|
189 | type: "number"
|
190 | coord:
|
191 | type: "object"
|
192 | properties:
|
193 | lat:
|
194 | type: "number"
|
195 | lon:
|
196 | type: "number"
|
197 | dt:
|
198 | type: "number"
|
199 | id:
|
200 | type: "number"
|
201 | main:
|
202 | type: "object"
|
203 | properties:
|
204 | humidity:
|
205 | type: "number"
|
206 | pressure:
|
207 | type: "number"
|
208 | temp_max:
|
209 | type: "number"
|
210 | temp_min:
|
211 | type: "number"
|
212 | temp:
|
213 | type: "number"
|
214 | name:
|
215 | type: "string"
|
216 | sys:
|
217 | type: "object"
|
218 | properties:
|
219 | country:
|
220 | type: "string"
|
221 | id:
|
222 | type: "number"
|
223 | message:
|
224 | type: "number"
|
225 | sunrise:
|
226 | type: "number"
|
227 | sunset:
|
228 | type: "number"
|
229 | type:
|
230 | type: "number"
|
231 | weather:
|
232 | type: "array"
|
233 | items:
|
234 | type: "object"
|
235 | properties:
|
236 | description:
|
237 | type: "string"
|
238 | icon:
|
239 | type: "string"
|
240 | id:
|
241 | type: "number"
|
242 | main:
|
243 | type: "string"
|
244 | wind:
|
245 | type: "object"
|
246 | properties:
|
247 | deg:
|
248 | type: "number"
|
249 | speed:
|
250 | type: "number"
|
251 | ```
|
252 |
|
253 | ### <a name="nextstep"></a>Next steps
|
254 |
|
255 | Now that you know have added a path, its time to [implement the actual controller](./controllers.md)
|