Skip to content
This repository was archived by the owner on Aug 5, 2019. It is now read-only.

Commit 7246c57

Browse files
authored
Merge pull request #2 from UCLCSSA/api-endpoints
Add generic API specification
2 parents 752116f + d8cb391 commit 7246c57

File tree

1 file changed

+257
-4
lines changed

1 file changed

+257
-4
lines changed

API-Specification.md

+257-4
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,272 @@
1-
# UCLCSSA API Specification
1+
# UCLCSSA API v1 Specification
22

33
## Introduction
44

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:
77

8+
- HTTP/1.1 network protocol: [RFC2616](https://tools.ietf.org/html/rfc2616)
89
- API style: [REST](https://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm)
910
- Data interchange format: [JSON](https://www.json.org/)
1011
- Client-Server communication protocol: [HTTP/1.1 @ RFC7230](https://tools.ietf.org/html/rfc7230)
1112
- Payload compression: [gzip](https://tools.ietf.org/html/rfc1952) and [Compression Codings @ RFC7230§4.2](https://tools.ietf.org/html/rfc7230)
1213

1314
Relevant REST information may be found at [Standards.REST](http://standards.rest/).
1415

16+
This API specification is modeled after [GitHub API v3](https://developer.github.com/v3/).
17+
1518
## Conventions Used in this Specification
1619

17-
The requirement level keywords "MUST", "MUST NOT", "REQUIRED", "SHALL",
20+
The requirement level keywords "MUST", "MUST NOT", "REQUIRED", "SHALL",
1821
"SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" used
1922
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

Comments
 (0)