--

๐—•๐—ฒ๐˜€๐˜ ๐—ฃ๐—ฟ๐—ฎ๐—ฐ๐˜๐—ถ๐—ฐ๐—ฒ๐˜€ ๐—ถ๐—ป Restful ๐—”๐—ฃ๐—œ ๐——๐—ฒ๐˜€๐—ถ๐—ด๐—ป

What is REST? โ€” It stands for Representational State Transfer.

REST API transfers a representation of a resource (data) that resides in the server (in the Database) to the client. The representation can be in the form of JSON, XML, or even in HTML.

The data that is transferred by REST API is organized according to a design. So, we can say REST is a data architecture.

Also, it always produces predictable and consistent outputs. REST API consists of six constraints.

  • What are the six constraints of REST API?
  1. Client โ€” Server Architecture โ€” This rule ensures the separation of concerns. Client manages the UI concerns while the Server manages the data persistence concerns. In return, we get a highly portable system where once REST API can manage different clients.
  2. Statelessness โ€” No client data can be stored on the server between requests. If the client state is relevant for the requests, it must be sent along with the requests. If server needs to save the client sessions, it should be saved in a DB for a given time of period.
  3. Cacheability โ€” All responses should be marked as cacheable or non-cacheable. If response can be changed constantly, we should not cache them. Cacheability matters for the performance of the REST API.
  4. Layered System โ€” Client cannot know / should not care whether it directly connected to the original server or intermediary along the way. It means REST allows you to have a layered system architecture and the request can be sent through different layers. This helps with security and scalability (CDN, authorization server).
  5. Code on demand โ€” REST API can transfer executable JavaScript files and compiled components to the client when needed.
  6. Uniform Interface โ€” As the name implies, there should be an interface for the resources which are exposed to the API clients. A resource in the server should have only one logical URI to retrieve or manipulate the resource.

There are four sub rules defined for this constraint.

They are:

1) Uniform Interface should have a unique resource identifier.

2) Uniform Interface Resource manipulation through representations. Once a client has a representation of a resource, it should be able to modify or delete it.

3) Uniform Interface must issue self-descriptive messages for sending and receiving representational data (content-type).

4) Hypermedia as the engine of application state. Once a client has access to a REST service, it should be able to discover all available resources and methods through the hyperlinks provided (Ex: curl https://api.github.com).

What is RESTful API? โ€” REST API can be derived using many protocols (Ex: HTTP, FTP). In practical an API which follows REST constraints + HTTP (use of HTTP methods) is called RESTful API.

So, if you want to implement a service,

  • based on client-server architecture
  • and want to serve different clients through HTTP protocol
  • and want to use the REST constraints described above

you can select RESTful architecture for your service.

The standard method of communication between the systems is through APIs. Therefore, itโ€™s crucial to properly build REST APIs to avoid issues in the future. A well-defined API should be ๐—ฒ๐—ฎ๐˜€๐˜† ๐˜๐—ผ ๐˜„๐—ผ๐—ฟ๐—ธ ๐˜„๐—ถ๐˜๐—ต, ๐—ฐ๐—ผ๐—ป๐—ฐ๐—ถ๐˜€๐—ฒ, ๐—ฎ๐—ป๐—ฑ ๐—ต๐—ฎ๐—ฟ๐—ฑ ๐˜๐—ผ ๐—บ๐—ถ๐˜€๐˜‚๐˜€๐—ฒ.

What is API Design?
API design refers to the process of developing application programming interfaces (APIs) that expose data and application functionality for use by developers and users.

The Importance of Knowing Use Cases:
When you understand how your software will be used you can design it better. The biggest mistake in API design is to make decisions based on how your system works, rather than what your consumers need to support. In order to design around use cases, youโ€™ll need to talk to the consumers, or at least include those who know them better.

Software is rarely built entirely by engineers. There are stakeholders throughout the organization. And while many engineers can be very product-minded, they donโ€™t always have the visibility of the full picture. If your organization has a product group, thatโ€™s often where the voice of the customer is most heard. Involve anyone who understands how an API will be used in discussions as you design the API. When you involve others in API design, you build something better.

API Design Best Practices:
Armed with an understanding of your use cases, youโ€™re ready to begin your API design. Each project is different, so best practices may not always fit your situation.

In general, an effective API design will have the following characteristics:

Easy to read and work with
Hard to misuse
Complete and concise

Here are some general recommendations:

๐Ÿญ. ๐—จ๐˜€๐—ฒ ๐—ป๐—ผ๐˜‚๐—ป๐˜€ ๐—ถ๐—ป๐˜€๐˜๐—ฒ๐—ฎ๐—ฑ ๐—ผ๐—ณ ๐˜ƒ๐—ฒ๐—ฟ๐—ฏ๐˜€

Verbs should not be used in endpoint paths. Instead, the pathname should contain the nouns that identify the object that the endpoint that we are accessing or altering belongs to.

E.g., instead of using http://api.movieservice.com/๐š๐šŽ๐š๐™ฐ๐š•๐š•Movies to fetch all clients, use http://api.movieservice.com/movies.

๐Ÿฎ. ๐—จ๐˜€๐—ฒ ๐—ฝ๐—น๐˜‚๐—ฟ๐—ฎ๐—น ๐—ฟ๐—ฒ๐˜€๐—ผ๐˜‚๐—ฟ๐—ฐ๐—ฒ ๐—ป๐—ผ๐˜‚๐—ป๐˜€

Try to use the plural form for resource nouns, because this fits all types of endpoints.

E.g., instead of using /movie/:๐š’๐š/, use /movies/:๐š’๐š/

๐Ÿฏ. ๐—•๐—ฒ ๐—ฐ๐—ผ๐—ป๐˜€๐—ถ๐˜€๐˜๐—ฒ๐—ป๐˜

When we say to be consistent, this means to be predictable. When we have one endpoint defined, others should behave in the same way. So, use the same case for resources, the same auth methods for all endpoints, use the same headers, use the same status codes, etc.

๐Ÿฐ. ๐—ž๐—ฒ๐—ฒ๐—ฝ ๐—ถ๐˜ ๐˜€๐—ถ๐—บ๐—ฝ๐—น๐—ฒ

We should make naming all endpoints to be resource-oriented, as they are. If we want to define an API for movies, we would define it as:

http://api.movieservice.com/v1/movies/
http://api.movieservice.com/v1/movies/๐Ÿท๐Ÿธ๐Ÿบ

So, the first API gets all movies and the second one gets a specific movie.

๐Ÿฑ. ๐—จ๐˜€๐—ฒ ๐—ฝ๐—ฟ๐—ผ๐—ฝ๐—ฒ๐—ฟ ๐˜€๐˜๐—ฎ๐˜๐˜‚๐˜€ ๐—ฐ๐—ผ๐—ฑ๐—ฒ๐˜€

This one is super important. There are many HTTP status codes, but we usually use just some of them. Donโ€™t use too many, but use the same status codes for the same outcomes across the API, e.g.,

- 200 for general success
- 201 for successful creation
- 202 (Accepted)
- 400 for bad requests
- 401 for unauthorized requests
- 403 for missing permissions
- 404 for missing resources
- 5xx for internal errors

202 (Accepted) for backend calls, which do not immediately can return a result for the desired request. This usually applies for long running processes, i.e. shrinking a video file or executing a BPMN process inside a workflow engine.

๐Ÿฒ. ๐——๐—ผ๐—ปโ€™๐˜ ๐—ฟ๐—ฒ๐˜๐˜‚๐—ฟ๐—ป ๐—ฝ๐—น๐—ฎ๐—ถ๐—ป ๐˜๐—ฒ๐˜…๐˜

REST APIs should accept JSON for request payload and also respond with JSON because it is a standard for transferring data. Yet, it is not enough just to return a body with JSON-formatted string, we need to specify a Content-Type header too to be application/json. The only exception is if weโ€™re trying to send and receive files between the client and server.

############################################################################
# Movie Apis Definitions #
############################################################################
# Code completion support is available so start typing for available options.
swagger: '2.0'

# This is your document metadata
info:
version: "1.0.1"
title: The movie api

# Describe your paths here
paths:
# This is a path endpoint. Change it.
/movies:
# This is a HTTP operation
get:
# Describe this verb here. Note: you can use markdown
description: Returns all movies
operationId: getMovies
# Expected responses for this operation:
responses:
# Response code
200:
description: Successful response
# A schema describing your response object.
# Use JSON Schema format
schema:
title: ArrayOfMovies
type: array
items:
$ref: '#/definitions/movie'
default:
description: Error
schema:
$ref: 'https://zalando.github.io/problem/schema.yaml#/Problem'
post:
description: Add a new movie
operationId: addMovie
parameters:
- name: movie
in: body
description: The new movie
required: true
schema:
$ref: '#/definitions/movie'
responses:
'201':
description: The new movie
schema:
$ref: '#/definitions/movie'
default:
description: Error
schema:
$ref: 'https://zalando.github.io/problem/schema.yaml#/Problem'
/movies/{id}:
parameters:
- name: id
in: path
description: ID of the movie
required: true
type: integer
format: int64
get:
description: Returns a single movie
operationId: getMovieById
responses:
200:
description: Successful response
schema:
$ref: '#/definitions/movie'
default:
description: Error
schema:
$ref: 'https://zalando.github.io/problem/schema.yaml#/Problem'
put:
description: Update an existing movie
operationId: updateMovieById
parameters:
- name: movie
in: body
description: The movie
required: true
schema:
$ref: '#/definitions/movie'
responses:
'200':
description: The new movie
schema:
$ref: '#/definitions/movie'
default:
description: Error
schema:
$ref: 'https://zalando.github.io/problem/schema.yaml#/Problem'
delete:
description: Delete a movie
operationId: deleteMovieById
responses:
'204':
description: Movie deleted
default:
description: Error
schema:
$ref: 'https://zalando.github.io/problem/schema.yaml#/Problem'
definitions:
movie:
type: object
required:
- id
- title
properties:
id:
type: integer
format: int64
title:
type: string
ratings:
type: object
properties:
criticsScore:
type: integer
minimum: 0
maximum: 100
audienceScore:
type: integer
minimum: 0
maximum: 100
criticsConsensus:
type: string
abridgedDirectors:
type: array
items:
type: string
abridgedCast:
type: array
items:
$ref: '#/definitions/cast'
posters:
$ref: '#/definitions/posters'
cast:
type: object
required:
- id
- name
properties:
id:
type: integer
format: int64
name:
type: string
characters:
type: array
items:
type: string
posters:
properties:
thumbnail:
type: string
format: uri
profile:
type: string
format: uri
detailed:
type: string
format: uri
original:
type: string
format: uri

7.Attribute Names in camelCase:

If you are using JSON it makes sense to follow JavaScriptโ€™s naming conventions especially if the consumer applications are likely to be written in javascript too. snake_case is easy to read but try to avoid it.

8. Cache data to improve performance:

The good thing about caching is that users can get data faster. We can add caching to return data from the local memory cache instead of querying the database to get the data every time we want to retrieve some data that users request.

9. ๐——๐—ผ ๐—ฝ๐—ฟ๐—ผ๐—ฝ๐—ฒ๐—ฟ ๐—ฒ๐—ฟ๐—ฟ๐—ผ๐—ฟ ๐—ต๐—ฎ๐—ป๐—ฑ๐—น๐—ถ๐—ป๐—ด

Here we want to eliminate any confusion when an error occurs, so we need to handle errors properly and return a response code that indicates what error happened (from 400 to 5xx errors). Along with a status code we need to return some details in the response body.

10. ๐—›๐—ฎ๐˜ƒ๐—ฒ ๐—ด๐—ผ๐—ผ๐—ฑ ๐˜€๐—ฒ๐—ฐ๐˜‚๐—ฟ๐—ถ๐˜๐˜† ๐—ฝ๐—ฟ๐—ฎ๐—ฐ๐˜๐—ถ๐—ฐ๐—ฒ๐˜€

We want that all communication between a client and a server is protected, which means that we need to use SSL/TLS all the time, with no exceptions. Also, allow auth via API keys, which should be passed using a custom HTTP header, with an expiration day.

  • Use OAuth2 to secure your API.
  • Use an auto-expiring Bearer token for authentication (Authorisation: Bearer f0ca4227-64c4-44e1-89e6-b27c62ac2eb6).
  • Require HTTPS.
  • Consider using JSON Web Tokens.
  • Enforce use of the Content-Type and Accept-Type headers even if you use JSON as default for both requests and responses.
e.g.  Content-Type: application/json Accept-Type: application/json
  • Responses contain header: X-Content-Type-Options: nosniff
  • Responses contain header: X-Frame-Options: deny

11. ๐—จ๐˜€๐—ฒ ๐—ฝ๐—ฎ๐—ด๐—ถ๐—ป๐—ฎ๐˜๐—ถ๐—ผ๐—ป

Use pagination if our API needs to return a lot of data, as this will make our API future-proof. Use page and page_size is recommended here.

E.g., http://api.movieservice.com/v1/movies?๐š™๐šŠ๐š๐šŽ=๐Ÿท0&๐š™๐šŠ๐š๐šŽ_๐šœ๐š’๐šฃ๐šŽ=๐Ÿธ0

๐Ÿญ2. ๐—ฉ๐—ฒ๐—ฟ๐˜€๐—ถ๐—ผ๐—ป๐—ถ๐—ป๐—ด

It is very important to version APIs from the first version, as there could be different users for our APIs. This will allow our users not to be affected by changes that we can do in the future. API versions can be passed through HTTP headers or query/path params.

E.g., http://api.movieservice.com/v1/movies/๐Ÿบ56789

And donโ€™t forget to ๐—ฑ๐—ผ๐—ฐ๐˜‚๐—บ๐—ฒ๐—ป๐˜ ๐—”๐—ฃ๐—œ, because API will be only good as its documentation. The docs should show examples of complete request/response cycles. Here we can use the OpenAPI definition as a source of truth.

Swagger is the most widely used standard for specifying and documenting REST Services. The real power of the Swagger standard comes from the ecosystem of powerful tools that surrounds it.

13.APIs also comply to the HATEOAS standard because it makes life easy for the consumers of your API

In 2008, Leonard Richardson proposed the following maturity model for web APIs:

  • Level 0: Define one URI, and all operations are POST requests to this URI.
  • Level 1: Create separate URIs for individual resources.
  • Level 2: Use HTTP methods to define operations on resources.
  • Level 3: Use hypermedia (HATEOAS, described below).

Level 3 corresponds to a truly RESTful API according to Fieldingโ€™s definition. In practice, many published web APIs fall somewhere around level 2.

If you want to start developing APIs, check Swagger and OpenAPI specifications, Postman, or Stoplight.

14. Implement and monitor an uncached /health endpoint, e.g.GET /api/health

     {    
"healthy": true,
"dependencies":
{ "name": "moviesapi",
"healthy": true
}
}

15. Idempotent operations

An operation is idempotent if it can be called multiple times without producing additional side-effects after the first call. Idempotency can be a useful resiliency strategy, because it allows an upstream service to safely invoke an operation multiple times.

The HTTP specification states that GET, PUT, and DELETE methods must be idempotent. POST methods are not guaranteed to be idempotent. If a POST method creates a new resource, there is generally no guarantee that this operation is idempotent. The specification defines idempotent this way:

A request method is considered โ€œidempotentโ€ if the intended effect on the server of multiple identical requests with that method is the same as the effect for a single such request. (RFC 7231)

Itโ€™s important to understand the difference between PUT and POST semantics when creating a new entity. In both cases, the client sends a representation of an entity in the request body. But the meaning of the URI is different.

  • For a POST method, the URI represents a parent resource of the new entity, such as a collection. For example, to create a new movie, the URI might be /api/movies. The server creates the entity and assigns it a new URI, such as /api/movies/6812360. This URI is returned in the Location header of the response. Each time the client sends a request, the server will create a new entity with a new URI.
  • For a PUT method, the URI identifies the entity. If there already exists an entity with that URI, the server updates the existing entity with the version in the request.

16.For multi-lingual APIs, use the Accept-Language header for locale setting (Accept-Language: nl, en-gb;q=0.8, en;q=0.7)

17. All endpoints return the Date header

Date โ€” Date and time the response was returned (in RFC1123 format) (Date: Sun, 06 Nov 1994 08:49:37 GMT)

18.Implement strong caching (by client, transport, proxy, etc.) through the cache-control response-header. As a minimum have public GET-endpoints return the following response headers:

  • Cache-Control โ€” The maximum number of seconds (ttl) a response can be cached. (Cache-Control: public, 360 or Cache-Control: no-store)
  • Strong caching minimizes the number of requests a server receives
  • Consider weak caching through the ETag response-header
  • ETag โ€” Use a SHA1 hash for the version of a resource. Make sure to include the media type in the hash value, because that makes a different representation. (ETag: "2dbc2fd2358e1ea1b7a6bc08ea647b9a337ac92d"). The client needs to send a If-None-Match header for this mechanism to work.
  • Weak caching minimizes the work a server needs to do (but not the number of requests it receives)
  • Enable header-based caching on all proxies and clients (e.g. NGINX, Apache, APIM) to increase speed and robustness
  • No privacy or security compromising data in URLโ€™s

19. For APIโ€™s that need content / payload encrypytion

  • Implement content encryption on the furthest endpoints (in the REST-server, not the proxies or APIM)
  • When content signing is used, this is done after the content is (optionally) encrypted.
  • Use the X-Signing-Algorithm header to communicate the type of content signing (X-Signing-Algorithm: RS256)
  • Use the X-SHA256-Checksum header to communicate the SHA256 hash value of the content (X-SHA256-Checksum: e1d58ba0a1810d6dca5f086e6e36a9d81a8d4bb00378bdab30bdb205e7473f87)
  • Use the X-Encryption-Algorithm header to communicate the type of content encryption (X-Encryption-Algorithm: A128CBC-HS256)

20 A good API (as any other interface) is

  • Consistent (avoid surprises by being predictable)
  • Cohesive (only lists endpoints with functional dependency)
  • Complete (has all necessary endpoints for its purpose)
  • Minimal (no more endpoints than necessary to be complete, no featurism)
  • Encapsulating (hiding implementation details)
  • Self explaining
  • Documented (if self explanation is not sufficient)

21 API Security : Api Security is becoming a well known and heavily used in most of the enterprise software systems. Every time you implement a digital transformation strategy within your organization, APIs have become the cornerstone of that strategy. There are many vendors who have solid solutions to implement this pattern. Here are some of the vendors.

Other Interesting Articles :

Many ways to learn GCP for Free with Google Cloud over the holidays

Understanding ๐—–๐—ข๐—ฅ๐—ฆ-๐—–๐—ฟ๐—ผ๐˜€๐˜€-๐—ข๐—ฟ๐—ถ๐—ด๐—ถ๐—ป ๐—ฅ๐—ฒ๐˜€๐—ผ๐˜‚๐—ฟ๐—ฐ๐—ฒ ๐—ฆ๐—ต๐—ฎ๐—ฟ๐—ถ๐—ป๐—ด

Linux Commands for Cloud Learning

Happy Readingโ€ฆ..

--

--

A Passionate Programmer - A Technology Enthusiast
A Passionate Programmer - A Technology Enthusiast

Written by A Passionate Programmer - A Technology Enthusiast

An Architect practicing Architecture, Design,Coding in Java,JEE,Spring,SpringBoot,Microservices,Apis,Reactive,Oracle,Mongo,GCP,AWS,Kafka,PubSub,DevOps,CI-CD,DSA

No responses yet