|
1 |
| -# UCLCSSA API Specification |
| 1 | +# UCLCSSA API v1 Specification |
2 | 2 |
|
3 | 3 | ## Introduction
|
4 | 4 |
|
5 |
| -This specification documents the API for interoperability between clients |
6 |
| -and services. The specification builds atop of: |
| 5 | +This specification documents the UCLSSA API v1 for interoperability between |
| 6 | +clients and services. The specification builds atop of: |
7 | 7 |
|
| 8 | +- HTTP/1.1 network protocol: [RFC2616](https://tools.ietf.org/html/rfc2616) |
8 | 9 | - API style: [REST](https://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm)
|
9 | 10 | - Data interchange format: [JSON](https://www.json.org/)
|
10 | 11 | - Client-Server communication protocol: [HTTP/1.1 @ RFC7230](https://tools.ietf.org/html/rfc7230)
|
11 | 12 | - Payload compression: [gzip](https://tools.ietf.org/html/rfc1952) and [Compression Codings @ RFC7230§4.2](https://tools.ietf.org/html/rfc7230)
|
12 | 13 |
|
13 | 14 | Relevant REST information may be found at [Standards.REST](http://standards.rest/).
|
14 | 15 |
|
| 16 | +This API specification is modeled after [GitHub API v3](https://developer.github.com/v3/). |
| 17 | + |
15 | 18 | ## Conventions Used in this Specification
|
16 | 19 |
|
17 |
| -The requirement level keywords "MUST", "MUST NOT", "REQUIRED", "SHALL", |
| 20 | +The requirement level keywords "MUST", "MUST NOT", "REQUIRED", "SHALL", |
18 | 21 | "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" used
|
19 | 22 | in this specification are intended to be interpreted according to [RFC2119](https://www.ietf.org/rfc/rfc2119.txt).
|
| 23 | + |
| 24 | +Relevant terminology from the `HTTP/1.1` (`RFC2616`) standard is used where |
| 25 | +appropriate, such as `header`, `body`. |
| 26 | + |
| 27 | +## Current API Version |
| 28 | + |
| 29 | +By default, all requests to `https://api.uclcssa.cn` SHALL dispatch to the `v1` |
| 30 | +REST API. All requests SHOULD explicitly include the `Accept` HTTP header for |
| 31 | +stability against API changes. |
| 32 | + |
| 33 | +``` |
| 34 | +Accept: application/vnd.uclcssa.v1+json |
| 35 | +``` |
| 36 | + |
| 37 | +For more details, refer to [Media Types](#media-types). |
| 38 | + |
| 39 | +## Schema |
| 40 | + |
| 41 | +All API communication MUST occur over HTTPS, at `https://api.uclcssa.cn`. The |
| 42 | +data interchange format used MUST be JSON. |
| 43 | + |
| 44 | +For example, the response to a request to `https://api.uclcssa.cn/users/testuser` |
| 45 | +fetching headers should return |
| 46 | + |
| 47 | +```http |
| 48 | +curl -i https://api.uclccsa.cn/users/testuser |
| 49 | +HTTP/1.1 200 OK |
| 50 | +Server: nginx |
| 51 | +Date: Thu, 13 Jun 2019 16:50:11 GMT |
| 52 | +Content-Type: application/json; charset=utf-8 |
| 53 | +Content-Encoding: gzip |
| 54 | +Content-Length: 5 |
| 55 | +Connection: keep-alive |
| 56 | +Status: 200 OK |
| 57 | +X-Media-Type: uclcssa.v1 |
| 58 | +X-Content-Type-Options: nosniff |
| 59 | +``` |
| 60 | + |
| 61 | +Suitable HTTP headers SHOULD be used to convey additional information, such as |
| 62 | +authentication, caching, API versioning and access control. See [HTTP Headers](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers) for more information. |
| 63 | + |
| 64 | +Notes: |
| 65 | +- `Date` format SHOULD conform to `HTTP-date` in [RFC7231](https://tools.ietf.org/html/rfc7231) |
| 66 | +- `Content-Encoding` SHOULD be specified to use `gzip`. |
| 67 | +- `X-*` headers are custom headers for additional metadata. |
| 68 | +- `X-Media-Type: uclcssa.v1` specifies the API version as `v1`. |
| 69 | +- There are no rate limits yet - restricting traffic flow, e.g. for |
| 70 | +load-balancing is not yet considered in `v1` API. |
| 71 | +- There are no caching support yet. |
| 72 | +- `Content-Length` specifies the size of the body in bytes, and MUST be |
| 73 | +included. |
| 74 | + |
| 75 | +Blank fields MUST be included with value `null` instead of being omitted. |
| 76 | + |
| 77 | +All timestamps MUST be returned in [RFC3339](https://tools.ietf.org/html/rfc3339) |
| 78 | +format. |
| 79 | + |
| 80 | +## Summary Representations |
| 81 | + |
| 82 | +When requesting a *list* of certain resources, only their *summary |
| 83 | +representations* are returned for performance reasons. |
| 84 | + |
| 85 | +For example, when trying to fetch a list of nearby restaurants, only the summary |
| 86 | +representations of the restaurants are returned. |
| 87 | + |
| 88 | +## Detailed Representations |
| 89 | + |
| 90 | +When requesting an individual resource, such as a `library`, all of its |
| 91 | +attributes and detailed information are returned, depending on the requester's |
| 92 | +permissions. |
| 93 | + |
| 94 | +## Authentication |
| 95 | + |
| 96 | +All authentication for restricting access to server resources MUST be handled |
| 97 | +via [OAuth 2.0](https://oauth.net/2/) mechanisms (hereafter abbreviated as |
| 98 | +`OAuth2`), standardized by |
| 99 | +[RFC6749](http://tools.ietf.org/html/rfc6749). |
| 100 | + |
| 101 | +Tutorials for `OAuth2` can be found at [bubblecode](http://www.bubblecode.net/en/2016/01/22/understanding-oauth2/). |
| 102 | + |
| 103 | +The user SHOULD register with WeChat authentication. The user SHOULD be able to |
| 104 | +additionally bind their WeChat id to their UCL email address for personalized |
| 105 | +UCL API related capabilities, such as personal timetables. |
| 106 | + |
| 107 | +Upon requesting any access-restricted resource, as such personal timetables, |
| 108 | +the client MUST send their OAuth2 `token` via the `Authorization` http header. |
| 109 | + |
| 110 | +For example, |
| 111 | + |
| 112 | +```http |
| 113 | +curl -H "Authorization: token {OAUTH-TOKEN}" https://api.uclcssa.cn |
| 114 | +``` |
| 115 | + |
| 116 | +### Failed Login Limit |
| 117 | + |
| 118 | +Upon receiving invalid credentials, the server MUST return `401 Unauthorized` |
| 119 | +status code to notify the client. |
| 120 | + |
| 121 | +Upon 5 requests trying to authenticate via invalid credentials, the server |
| 122 | +MUST reject any authentication requests from the client for 10 minutes, |
| 123 | +beginning from the fifth failed attempt, with the status code `403 Forbidden`. |
| 124 | + |
| 125 | +## Parameters |
| 126 | + |
| 127 | +For `GET` requests, parameters SHOULD be passed as `HTTP query string parameter`, |
| 128 | +with the format `https://api.uclcssa.cn/resource?{key1}={value1}&{key2}={value2}`. |
| 129 | + |
| 130 | +That is, query string parameters are suffixes to the URI of the resource, |
| 131 | +beginning with query operator `?`, then followed by key-value pairs, with |
| 132 | +multiple pairs conjuncted with the `&` operator. |
| 133 | + |
| 134 | +Additional data SHALL be sent as `JSON` body (i.e. `Content`). |
| 135 | + |
| 136 | +## Client Errors |
| 137 | + |
| 138 | +If clients send requests with invalid JSON body, that is, if clients send: |
| 139 | + |
| 140 | +1. **Invalid JSON**: The server MUST return with `400 Bad Request` response. |
| 141 | + |
| 142 | +```http |
| 143 | +HTTP/1.1 400 Bad Request |
| 144 | +Content-Length: 31 |
| 145 | +
|
| 146 | +{"message":"Cannot parse JSON"} |
| 147 | +``` |
| 148 | + |
| 149 | +2. **Incorrect JSON value types**: The server MUST return with `400 Bad Request` |
| 150 | +response. |
| 151 | + |
| 152 | +```http |
| 153 | +HTTP/1.1 400 Bad Request |
| 154 | +Content-Length: 40 |
| 155 | +
|
| 156 | +{"message":"Incorrect JSON value types"} |
| 157 | +``` |
| 158 | + |
| 159 | +3. **Invalid fields**: The server MUST return with `422 Unprocessable Entity` |
| 160 | +response. |
| 161 | + |
| 162 | +```http |
| 163 | +HTTP/1.1 422 Unprocessable Entity |
| 164 | +Content-Length: 149 |
| 165 | +
|
| 166 | +{ |
| 167 | + "message": "Validation Failed", |
| 168 | + "errors": [ |
| 169 | + { |
| 170 | + "resource": "Library", |
| 171 | + "field": "title", |
| 172 | + "code": "missing-field" |
| 173 | + } |
| 174 | + ] |
| 175 | +} |
| 176 | +``` |
| 177 | + |
| 178 | +Each `error` object in `errors` SHOULD contain `resource`, `field` and `code` |
| 179 | +entries for diagnostics. |
| 180 | + |
| 181 | +Possible validation error codes include: |
| 182 | + |
| 183 | +| Error Code | Description | |
| 184 | +| ----------------- | --------------------------------------------- | |
| 185 | +| `missing` | Resource does not exist. | |
| 186 | +| `missing-field` | Required field missing. | |
| 187 | +| `invalid` | Incorrect formatting. | |
| 188 | +| `duplicate` | Resource with identical value already exists. | |
| 189 | + |
| 190 | +Resources MAY also respond with `custom` error codes, which means they MUST |
| 191 | +then have a complementary `message` field for describing the problem. |
| 192 | + |
| 193 | +For example, |
| 194 | + |
| 195 | +```http |
| 196 | +HTTP/1.1 422 Unprocessable Entity |
| 197 | +Content-Length: 191 |
| 198 | +
|
| 199 | +{ |
| 200 | + "message": "Validation Failed", |
| 201 | + "errors": [ |
| 202 | + { |
| 203 | + "resource": "Library", |
| 204 | + "field": "title", |
| 205 | + "code": "custom", |
| 206 | + "message": "UCL API service unavailable" |
| 207 | + } |
| 208 | + ] |
| 209 | +} |
| 210 | +``` |
| 211 | + |
| 212 | +## HTTP Redirects |
| 213 | + |
| 214 | +Clients SHOULD assume that any requests to resources may cause a redirect |
| 215 | +response, which clients SHOULD follow. |
| 216 | + |
| 217 | +Redirect responses MUST contain the `Location` header field which specifies the |
| 218 | +destination URI of the resource. |
| 219 | + |
| 220 | +| HTTP Status Code | Description | |
| 221 | +| ---------------- | --------------------------------------------------------- | |
| 222 | +| `301` | Permanent redirection. Clients SHOULD migrate to new URI. | |
| 223 | +| `302`, `307` | Temporary redirection. Clients SHOULD use original URI. | |
| 224 | + |
| 225 | +## HTTP Verbs |
| 226 | + |
| 227 | +Suitable HTTP Verbs SHOULD be used to convey action semantics: |
| 228 | + |
| 229 | +| HTTP Verb | Description | |
| 230 | +| --------- | ----------------------------- | |
| 231 | +| `HEAD` | Get only header information. | |
| 232 | +| `GET` | Fetching resource. | |
| 233 | +| `POST` | Create resource. | |
| 234 | +| `PATCH` | Update resource. | |
| 235 | +| `PUT` | Replace resource. | |
| 236 | +| `DELETE` | Delete resource. | |
| 237 | + |
| 238 | +## Pagination |
| 239 | + |
| 240 | +Requests which return list containing multiple items SHOULD be paginated with |
| 241 | +30 items be default. Clients SHOULD be able to specify custom pages via |
| 242 | +the `?page={PAGE_NUMBER}` query parameter. Page numbers MUST begin at `1`. |
| 243 | +Clients SHOULD be able to specify items per page via `?per_page={NUM_ITEMS}`. |
| 244 | + |
| 245 | +For feed pagination, the client SHOULD be responsible for storing the latest |
| 246 | +post id. The server SHOULD allow the client to access posts by offset, e.g. |
| 247 | + |
| 248 | +```http |
| 249 | +/posts?offset={OFFSET_AMOUNT}&per_page={NUM_ITEMS} |
| 250 | +``` |
| 251 | + |
| 252 | +## User Agent |
| 253 | + |
| 254 | +Clients MUST supply a valid `User-Agent` header in their requests. |
| 255 | + |
| 256 | +For the WeChat app, the `User-Agent` should take the form |
| 257 | + |
| 258 | +```http |
| 259 | +User-Agent: UCLCSSA-WeChat-App ("{PLATFORM}"; rv:"{VERSION}") |
| 260 | +``` |
| 261 | + |
| 262 | +Where `{PLATFORM}` is the native platform information, e.g. `iOS` or `Andriod`, |
| 263 | +and `{VERSION}` is the client version. |
| 264 | + |
| 265 | +For example, for UCLCSSA WeChat App on iOS with version `1.0.0-rc1`, its |
| 266 | +`User-Agent` should be |
| 267 | + |
| 268 | +```http |
| 269 | +User-Agent: UCLCSSA-WeChat-App ("ios"; rv:"1.0.0-rc1") |
| 270 | +``` |
| 271 | + |
| 272 | +This allows for diagnostics and user-agent monitoring. |
0 commit comments