Fabio Pitino
fabio_pitino@symantec.com
# Resource
/tickets/1234
# Collection of resources
/tickets
# Nested resources / Associations
/tickets/1234/files
POST /createTicket
# create a resource
POST /tickets + { "data": "value" }
# submit a search with long parameters
POST /search/tickets + { "data": "value" }
GET /getAllTickets
GET /getTicket/1234
# get a collection of tickets
GET /tickets
# get a ticket by id
GET /tickets/1234
# get comments for a ticket (nested resource)
GET /tickets/1234/comments
POST /updateTicket
PUT /escalateTicket
# replace comment
PUT /comments/1234 + { "text": "I changed my mind" }
# update ticket
PATCH /tickets/1234 + { "summary": "A new summary" }
POST /deleteTicket
PUT /cancelOrder
# delete ticket
DELETE /tickets/1234
# cancel order
DELETE /order/1234
# deactivate user
DELETE /users/1234
# Filters
GET /tickets?status=done&assignee_id=1897
# Sorting
GET /tickets?sort=priority_asc
# Text search
GET /tickets?q=Watchdog
# Pagination
GET /tickets?page=2&per_page=10
# Also possible to combine them
GET /tickets?status=done&sort=priority_asc&page=2
# Standard success response across all methods
Status: 200 OK
# When a new resource is created.
Status: 201 Created
Location: /tickets/1234
# When requesting long running jobs
Status: 202 Accepted
# When the response has no content
# E.g DELETE /tickets/1234
Status: 204 No Content
# Server did not understand the request. E.g: missing or
# invalid parameters
Status: 400 Bad Request
# Credentials are required to perform this action
Status: 401 Unauthorized
# Although the user is authenticated it does not have
# permissions to perform this action
Status: 403 Forbidden
# The resource is not available
Status: 404 Not Found
# If the server relies on 3rd party services to perform
# the action
Status: 408 Request Timeout
# The resource is no longer available. E.g: this version
# of API is no longer supported or the resource is not
# available due to retention period
Status: 410 Gone
# The request format was valid but something unexpected
# happened on the server
Status: 500 Server Error
# Server is temporary offline. Usually under maintenance
Status: 503 Service Unavailable
# some of the most common ones
Accept: application/json
Accept: application/vnd.github.v3+json
Authorization: Token token=QWxhZGRpbjpvcGVuIHNlc2FtZQ
Content-Type: application/json
User-Agent: MyClientLibrary/2.3
# for redirection or when a resource is created
Location: https://example.com/tickets/1234
# Server name
Server: Apache/2.4.1 (Unix)
# Pagination via headers
Link: <https://api.github.com/user/repos?page=3&per_page=100>; rel="next",
<https://api.github.com/user/repos?page=50&per_page=100>; rel="last"
# metadata using custom headers
Total-Count: 245
# send warning messages without altering the response
Warning: 199 - "This is a warning you may want to report"
# GET /tickets/123
{
"type": "Ticket",
"id": 123,
"url": "https://example.com/tickets/123",
"summary": "A ticket for HATEOAS",
"reporter": {
"type": "User",
"id": 5678,
"url": "https://example.com/users/5678",
"login": "fabio_pitino",
"email": "fabio_pitino@example.com"
},
"tags_url": "https://example.com/tickets/123/tags",
"comments_url": "https://example.com/tickets/123/comments",
"actions": [
"close_url": "https://example.com/tickets/123/close",
"block_url": "https://example.com/tickets/123/block",
"assign_url": "https://example.com/tickets/123/assign"
]
}
GET /repos/:owner/:repo/projects
# ******* headers *******
# Status: 200 OK
# Link: <https://api.github.com/resource?page=2>; rel="next",
# <https://api.github.com/resource?page=5>; rel="last"
[
{
"owner_url": "https://api.github.com/repos/api-playground/projects-test",
"url": "https://api.github.com/projects/1002604",
"html_url": "https://github.com/api-playground/projects-test/projects/12",
"columns_url": "https://api.github.com/projects/1002604/columns",
"id": 1002604,
"name": "Projects Documentation",
"body": "Developer documentation project for the developer site.",
"number": 1,
"state": "open",
"creator": {
"login": "octocat",
"id": 1,
"avatar_url": "https://github.com/images/error/octocat_happy.gif",
"gravatar_id": "",
"url": "https://api.github.com/users/octocat",
"html_url": "https://github.com/octocat",
"followers_url": "https://api.github.com/users/octocat/followers",
"following_url": "https://api.github.com/users/octocat/following{/other_user}",
"gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
"starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
"organizations_url": "https://api.github.com/users/octocat/orgs",
"repos_url": "https://api.github.com/users/octocat/repos",
"events_url": "https://api.github.com/users/octocat/events{/privacy}",
"received_events_url": "https://api.github.com/users/octocat/received_events",
"type": "User",
"site_admin": false
},
"created_at": "2011-04-10T20:09:31Z",
"updated_at": "2014-03-03T18:58:10Z"
}
]
github.com
# Status: 400 Bad Request
{
"errors": [
"Ticket summary was too short. Minimum 10 characters",
"Ticket priority must be between 1 and 4"
]
}
# *** VERBOSE VERSION ***
# Status: 400 Bad Request
{
"errors": [
{
"code": "123",
"source": { "pointer": "/data/attributes/summary" },
"title": "Value is too short",
"detail": "Ticket summary must contain at least 10 characters"
},
{
"code": "225",
"source": { "pointer": "/data/attributes/priority" },
"title": "Value not in range",
"detail": "Ticket priority must be between 1 and 4"
}
]
}
# HTTP Basic
> GET https://watchdog.symantec.com/api/tickets/1234
# Headers:
# Authorization: Basic QWxhZGRpbjpPcGVuU2VzYW1l
# >> base64( <username>:<password> )
# HTTP Basic (deprecated)
GET https://Aladdin:OpenSesame@watchdog.symantec.com/api/tickets/1234
# --------------------
# Bearer (token) Authentication
> POST https://watchdog.symantec.com/api/login
> data >> { username: 'aladdin', password: 'opensesame' }
< 200 OK
< {
< "token": "QWxhZGRpbjpPcGVuU2VzYW1lQWxhZGRpbjpPcGVuU2VzYW1l",
< "expires_at": "2019-02-23 00:00:00"
< }
> GET https://watchdog.symantec.com/api/tickets/1234
# Headers:
# Authorization: Bearer QWxhZGRpbjpPcGVuU2VzYW1lQWxhZGRpbjpPcGVuU2VzYW1l
# variant of Token Authentication
# Generate an application token via a frontend service
# use it in the URI
> GET https://watchdog.symantec.com/api/tickets/1234?API_TOKEN=QWxhZGRpbjpPcG...
# OAuth
# Open standard for secure delegated access to server resources on
# behalf of the resource owner
https://oauth.net/2/
# simple versioning in the URI
POST https://example.com/api/v1/tickets
# in the Accept request header
Accept: application/vnd.github.v3+json
# in a custom request header
api-version: 2.4
# in the URI as date
POST https://example.com/api/2017-02-28/tickets
> GET /tickets/123
< 200 OK
< Date: Mon, 29 May 2017 15:30:00 GMT
< Last-Modified: Sat, 27 May 2017 12:00:00 GMT
< ... response body ...
> GET /tickets/123
> If-Modified-Since: Mon, 29 May 2017 15:30:00 GMT
< 304 Not Modified
# ************************************************
> GET /tickets/123
< 200 OK
< Date: Mon, 29 May 2017 15:30:00 GMT
< Cache-control: max-age=120
< ... response body ...
> GET /tickets/123
> If-Modified-Since: Mon, 29 May 2017 15:32:00 GMT
< 304 Not Modified
> GET /tickets/123
< 200 OK
< ETag: "xf8ab201e123a3bc"
< ... data here ...
> GET /tickets/123
> If-None-Match: "xf8ab201e123a3bc"
< 304 Not Modified
# **********************************
> PATCH /tickets/123
> If-Match: "xf8ab201e123a3bc"
< 412 Precondition Failed
fabio_pitino@symantec.com