Oracle APEX and RESTful API standards
Web services guidelines
Consistent RESTFul APIs
For the past few month I have been involved in corporate level interoperability project and these are my few key "lessons-learned" notes.
We know and we have all heard of RESTful services and how important they are today for any production systems that are exchanging data.
Point here is to emphasize importance of having standards to provide guidelines for architects and developers in the design and development of RESTful APIs that are consistent, usable, max reusable and are based on current industry best practices.
Similar to your PL/SQL and Oracle APEX standards these are things that will evolve over time but key thing is to consider having them before development work begins.These guidelines are applicable regardless if your services are built with Oracle APEX, PHP or any other technology.
I will try to keep short and sweet as I am sure a lot can be said on this topic.
Overall summary would be:
REST Guidelines Summary
|
A REST URI identifies a resource
|
REST URIs should include nouns, not verbs
|
Use plural nouns to represent resources for consistency (no singular nouns)
|
Use HTTP verbs (GET, POST, PUT, DELETE) to operate on resource collections and elements
|
Use HTTP headers to include meta-data where possible
|
Use the correct HTTP status codes for responses
|
Control the depth and try not to nest deeper than /resource/{id}/resource if possible
|
Version the API using major, minor and patch version numbers, e.g. v1.0.0
|
Put the major version number in the URI, prepended with a ‘v’, for example https://my-resturl.com/v1/resource
|
Develop services that are idempotent, i.e. (accidentally) invoking the service twice with an identical payload has no undesirable side effects
|
Handle concurrency for 'unsafe' methods (i.e. PUT, POST, DELETE) where required
|
Default on using the JSON format for request and response messages
|
Use lowerCamelCase JSON message formats
|
All incoming and outgoing dates and times comply with the ISO8601 standard
|
All dates and times returned by a service should use the following ISO8601 compliant UTC common format: YYYY-MM-DDThh:mm:ss.sssZ
|
Wrap responses and error messages using a standardised format
|
Use the Common Information Model (CIM) where available
|
Always use HTTPS to secure the API at the transport layer
|
< Use OAuth 2.0 for token based security
|
Never change service features that have been released
|
As a consumer of a REST service: ignore content that is not used
|
Global guidelines
Design before build - The desired behavior of the API,
including endpoints and message examples, must be designed, documented and
reviewed before implementation starts.
OpenAPI specification - APIs must be specified using the OpenAPI Specification which is a well-established and widely adopted standard that allows both humans and computers to understand the capabilities of a service, without having to access the source code.
Include
the major version number in the URI
- The major version should be prepended with the letter ‘v’ to form the URI as
it improves 'explorability' via a browser address bar:
https://my-resturl.com/v1/projects
Use plural nouns for resource names - This makes interfaces more intuitive to use and avoids having to
deal with unusual pluralisation, such as diagnosis/diagnoses
/employee
/diagnoses/1234
Use hyphens in URIs for resource names
that consist of multiple words
/v1/employee-profile
Use lowerCamelCase for URI query parameters - This
is consistent with the default notation for JSON messages
/projects/1234?select=name,startDate,finishDate
Avoid using verbs in resource names - it may be convenient to use a verb to indicate a status change of
a resource. The following URI may be implemented to activate a project:
POST
/projects/1234/activate
Don’t use verbs in the URI
for CRUD-type operations, e.g.:
Incorrect:
GET
/GetAllProjects
Correct:
Resource
|
Expected Behaviour
|
GET /projects
|
Retrieve a list of
projects
|
POST /projects
|
Create a new project
|
PUT /projects
|
Bulk update complete
project records
|
PATCH /projects
|
Bulk update partial
project records
|
DELETE /projects
|
Delete all projects
|
GET /projects/1234
|
Retrieve a specific
project
|
POST /projects/1234
|
Usually invalid, but
may be used when the consumer is allowed to provide the primary ID in a
create resource request
|
PUT /projects/1234
|
Update all
attributes of a specific project
|
PATCH /projects/1234
|
Update one or more
attributes of a specific project
|
DELETE /projects/1234
|
Delete a specific
project
|
Use the appropriate HTTP status codes to indicate Success and Failure
Implemented services in such a way that they are idempotent -
multiple requests to a service with an
identical payload have no adverse effects to the overall state of the resource.
Detect concurrent modifications - Unsafe
methods (i.e. methods changing resources) must consider the need to detect
concurrent modifications. A common way to implement this is to have a read
(GET) operation on the resource include an HTTP ETag header containing a digest
(hash, e.g. MD5) representing the state of the resource.
Message format defaults to JSON
- JSON is more lightweight than XML and just as easy for humans to understand.
In addition, no parsing is required by JavaScript clients to use JSON messages.
Do not store values in keys of a JSON object
Correct:
{
"gender": [
{ "code":
"M", "description": "Male" }
]
}
Empty fields - Empty fields in response messages should be included as
null instead of being omitted.
Timestamps
- All timestamps
accepted and returned by the service ideally must be in ISO 8601 format [5]
with time zone information.
Validate all input fields - basic check like i.e. required and unique parameter, string, number types or follows certain pattern
Restrict usage of wildcards - for performance; check if at least one parameter is supplied
Collection of data
Enable
pagination of collections by using the standard keywords ‘limit’ and ‘offset’.
Define
an appropriate default limit that makes to prevent unnecessary use of bandwidth
and resources.
Use
the standard keyword ‘sort’ to indicate sorting of collections. Use ‘+’ to
indicate ascending sort direction, use ‘-‘ to indicate descending sort
direction. If no direction is specified, the default sort direction should be
ascending.
Error
messages
Must include the following
information:
·
a HTTP status code;
·
a link to the resource causing the
error;
·
a short error message;
·
a longer description explaining the
cause of the error.
Avoid exposing detailed system log messages to the consumers on production systems.
Security
All REST services should be exposed through the HTTPS
protocol to provide security at the transport layer.
Services should use OAuth 2.0 to support token based
authentication.
API
designers and developers should avoid exposing sensitive information like user
names, API keys, security tokens or other credentials on the URI.
It
is not enough to rely on consumers of the service to validate the input of
end-users. The API is responsible for checking that the data provided in the
service request conforms to business rules and does not pose a threat from a
security perspective (e.g. SQL and NoSQL injection, Cross Site Scripting).
REST services, particularly
services that are exposed to the public, must be monitored using an API
Management Tool
Conclusion:
Luckily once we have all of this in place APEX makes it easy to consume your newly created APIs. To make your life easier check out REST Client assistant packaged app and start from here. :)
Happy APEXing
SLino