Mindmap
Rest APIs
Inhalt der Mindmap
Rest APIs
Architectural style based on a client-server model
Resources (the nouns)
- Resource Naming
- uniquely identifiable in an API
- Resource name: //api.opleidingsgroep.nl/courses/123 Resource URL(HTTP): http://api.opleidingsgroep.nl/v1/courses/123 Resource describing noun part: course
- Should always use nouns and NOT verbs
- Correct: /users, /user-settings Incorrect: /get-users, /get-user-settings
- SHOULD always use concrete naming rather than abstract naming; On the other hand, it is also bad to end up with hundreds of resources due to extreme concretization; the recommendation is to aim for concrete but keep it manageable.
- Good abstraction: /dogs - medium abstraction (recommended) Inappropriate abstractions: /things - highest abstraction /animals - high abstraction /beagles - too low abstraction
- MUST always use lowercase for resource names
- Correct:/dogs Incorrect: /Dogs
- Compound resource names MUST use spinal-case
- Correct: /student-assignments Incorrect: /studentAssignments, /student-Assignments, /Student-assignments
- uniquely identifiable in an API
- Resource expansion
- { "id":"123", "name":"demo order", "clientId":"2" } With expand=client,orderItems { "id":"123", "name":"demo order", "clientId":"2", "embedded": { "client": { "id":"2", "name":"demo client" }, "orderItems": [ { "id":"456", "name":"demo order item", "price":10 }, { "id":"789", "name":"demo order item2", "price":15 }, ] } }
- loading both the respective resource as well as its associated data (sub-resources, stand-alone resources related to it)
- Query string parameter named $expand; the value of this parameter will be a comma separated list of item names that can be expanded.
- Collection Resources
- Indexed Pagination
- limit - represents the number of results that should be returned from the collection (equivalent to records per page a.k.a. page size)
- offset - represents the position from which the data will be fetched (equivalent to "start from"), offset = 0 specifies the first position, negative values should not be accepted
- GET /courses?offset=30&limit=10
- Structure - HATEOAS
- { "items": [ {"id": "1", "name": "Management", ... }, {"id": "2", "name": "Management2", ... }, ... ], "links": { { "rel":"self", "href":"https://.../courses?offset=10&limit=10" } { "rel":"next", "href": "https://.../courses?offset=20&limit=10", }, { "rel":"prev", "href": "https://.../courses?offset=0&limit=10", }, { "rel":"first", "href": "https://.../courses?offset=0&limit=10", }, { "rel":"last", "href": "https://.../courses?offset=60&limit=10", } }, "metadata": { "pagination": { "limit": 10, "offset": 0, "count": 10, "total": 65 }, "etags": { ... }, ... } }
- items
- links (pagination)
- metadata
- SHOULD be named at plural
- /users
- Simple resources - always part of a collection resource
- /users/123
- identifiers of simple resources are RECOMMENDED to be obfuscated in order to prevent incremental attacks; MINT library CAN be used to encode sensitive identifiers; in other words, sensitive identifiers from the Data storage should be exposed in an obfuscated manner.
- Indexed Pagination
- Resource Naming
Operations on Resources (the verbs)
- GET
- GET an individual resource: GET http://api.opleidingsgroep.nl/v1/courses/123 GET a collection resource: GET http://api.opleidingsgroep.nl/v1/courses
- Returns the current value of a resource/collection resource
- Returns 200 OK if the resource/collection resource exists
- Returns 404 Not Found if the resource/collection resources does not exist
- POST
- used to primarily for the creation of single resources that are part of a collection resource
- SHOULD result in the creation of a new single resource that is part of the collection resource; the new resource is passed as payload in the body of the request.
- SHOULD return the newly created resource.
- successful POST requests will usually generate 201 (if resources have been created), and 202 (if the request was accepted but has not been finished yet
- POST https://api.opleidingsgroep.nl/v1/courses/ Will result in the following response: 201 Created
- PUT
- used to replace entire resources - thus they have the semantics of a replace and not update.
- for non-existing resources SHOULD fail with a status code of 404 Not found (UPSERT functionality to be avoided)
- successful request replaces the entire resource with the new resource data
- SHOULD return the replaced resource with a status code of 200
- Highly discouraged: clients that do not understand (and hence ignore) properties on a resource are not likely to provide them on a PUT when trying to update a resource, hence such properties could be inadvertently removed
- PATCH
- [ { "op": "test", "path": "/a/b/c", "value": "foo" }, { "op": "remove", "path": "/name" }, { "op": "add", "path": "/a/b/c", "value": [ "foo", "bar" ] }, { "op": "replace", "path": "/name", "value": "abc" }, { "op": "move", "from": "/a/b/c", "path": "/a/b/d" }, { "op": "copy", "from": "/a/b/d", "path": "/a/b/e" } ]
- used for partial update of single resources
- requests for non-existing resources SHOULD fail with a status code of 404 (Not found)
- successful requests, the server will update the parts of the resource defined by the change request in the payload
- successful requests SHOULD return the fully updated resource with a status code of 200
- DELETE
- used to delete single resources
- successful request will generate a 204 status code, if the resource is deleted immediately, or a 200 status code (together with the status code) if the resource is just flagged for deletion.
- requests for non-existing resources SHOULD fail with a status code of 404 (Not found)
- GET
Relations between Resources
- The relation can only exist within another resource (scoped)
- GET /tickets/123/messages - retrieves a list of messages for ticket #123 GET /tickets/123/messages/5 - retrieves message #5 for ticket #123 POST /tickets/123/messages - creates a new message for ticket #123
- SHOULD NOT go beyond one level - the URL should not be deeper than the ones shown above (2 resources).
- The relation can exist independently of the resource; just include the identifier of the child resource inside the parent resource, and then just use the dedicated child endpoint to access it based on its ID
- /courses - labelId/labels
- The relation can only exist within another resource (scoped)
Errors
- 4xx status codes - client errors
- 1st level validation errors
- light validation checks performed on the direct input of the API operation, that do not require intensive server-side checks; E.g.: required fields, range checks, fields format (email, date, etc.),
- this type of issues SHOULD fail fast
- structure
- { "error":{ "code":"567", "message":"Validation failed", "modelState":{ "model.Password":[ "The Password must be at least 6 characters long." ], "model.ConfirmPassword":[ "The password and confirmation password do not match." ] } } }
- 2nd level validation errors
- usually heavy validation checks that involve medium to complex server-side operations (like DB requests, business rules checks, etc.)
- SHOULD fail as soon as encountered, thus stopping the execution process on the first encountered error.
- structure
- { "error":{ "code":"123", "message":"Project Id not provided", "description":"Project Id is a required field" } }
- 1st level validation errors
- 5xx status codes - server errors
- 4xx status codes - client errors
was designed to work with HTTP in order to enforce one of its main constraints - statelesness
Informationen
- Beschreibung
- Mindmap am Rest APIs, erstellt von Cristina Ionescu am 27/03/2019.
- Erstellt von
- Cristina Ionescu
- Aufrufe
- 13
- Bewertung