Any software you design will be used in ways you did not anticipate, that is especially true when you are design API’s which nowadays refers to Web REST APIs. There are different audiences or users for any API. There are the direct API users you know of that are defined in the specifications or solution design/architecture documents, like Web or Mobile clients for example. Then there are the ones you did not anticipate that would come at later stages. For example the API might be used to synchronize data with another system or to extract data for migration to another system. Nowadays, APIs are being considered as assets that would live longer than the projects or systems they are being built for. Taking that into account, there are many things that needs to be considered when designing an API. Let us assume we are designing and API for Authors/Books microservice as shown in the diagram below.
In the Book Author example, we want to implement CRUD (Create, read, Update and Delete) API for Author and Book entities. The requirements for this API
-
Search and listing functionality to:
- Get a List Authors with various search terms
- Get author books
- Search books by Author, Genre
- Add, update, delete Author or Book
To implement these requirements and have this API as an asset for later use we take the following steps
1: Define the Data type for the API Data Objects
Based on the requirement we first define the schemas for the Author and Book objects that the API will support.
For each resource the API supports we define a schema for:
- Data Manipulation Object
- Full object
- Full Object with HATEOAS (Links for operations)
In RAML we can define those objects as follows :
#%RAML 1.0
title: GT Books API Types
types:
AuthorMod:
description: This is Author for Data Manipulation
type: object
properties:
Name:
required: true
example: Moustafa Refaat
description: Author Name
type: string
Nationality:
required: true
example: Canadian
description: ‘Author Nationality ‘
type: string
Date-of-Birth:
required: true
example: ‘2018-12-09‘
description: Author Date of Birth
type: date-only
Date-of-Death:
required: false
example: ‘2018-12-09‘
description: Author Date of Death
type: date-only
Author:
description: This is the Full Author
type: AuthorMod
properties:
Id:
required: true
example: 1
description: Author Id
type: integer
Age:
required: false
maximum: 200
minimum: 8
example: 10
description: Author Age
type: integer
AuthorHateoas:
description: Author with Hateoas information LINKS
type: Author
properties:
Links:
required: true
description: Property description
type: array
items:
required: true
type: Link
BookMod:
description:
Book Info for Data Manipulation
type: object
properties:
AuthorId:
required: true
example: 1
description: Author Id
type: integer
Name:
required: true
example: Example
description: Book Name
type: string
Genre:
required: true
example: Example
description: Book Genre
type: string
Stars-Rating:
required: false
maximum: 5
minimum: 0
example: 1
description: Book Rating
type: integer
ISBN:
required: true
example: Example
description: Book ISBN
type: string
PublishDate:
required: true
example: ‘2018-12-09‘
description: Book Publish Date
type: date-only
Book:
description: Book Info
type: BookMod
properties:
Id:
required: true
example: 1
description: Book Id
type: integer
AuthorName:
required: true
example: Moustafa Refaat
description: Author Name
type: string
BookHateoas:
description: Book Information with Hateoas links
type: Book
properties:
Links:
required: true
description: Property description
type: array
items:
required: true
type: Link
Link:
description: Hateoas LINK
type: object
properties:
href:
required: true
example: /Book/10
description: URL Link
type: string
rel:
required: true
example: GetBook
description: Operation
type: string
method:
required: true
example: GET
description: ‘HTTP Method Get, PUT,..‘
type: string
2: Define URLs Resources for the API
For each Resource define and implement all the HTTP methods (Get, Post, Put, Delete, Patch, Head, Options) even if you are not going to use them now. You can make the implementation return “403 forbidden” message to the client to indicate that this operation is not supported. For our example we will have
-
/Authors
- Get: Search/List Authors, return body list of authors matching the search/list criteria with headers containing the paging information
- Post: Create a new Author, return created author
- Put: Not Supported return “403 Forbidden” error
- Delete: Not Supported return “403 Forbidden” error
- Patch: Not Supported return “403 Forbidden” error
- Head: Return empty body
- Options: returns the supported methods by this resource “Get, Post, Head, Options”.
-
/Authors/{id}
- Get: return author with supplied ID
- Post: Not Supported return “403 Forbidden” error
- Put: Update the author and return the updated author
- Delete: Deletes the author
- Patch: Not Supported return “403 Forbidden” error
- Head: Not Supported return “403 Forbidden” error
- Options: returns “Get, Put, Delete, Options”
-
/Authors/{id}/Books
- Get: Search/List of books for Author, return body list of books matching the search/list criteria with headers containing the paging information
- Post: Create a new book for author with Id returns created Book
- Put: Not Supported return “403 Forbidden” error
- Delete: Not Supported return “403 Forbidden” error
- Patch: Not Supported return “403 Forbidden” error
- Head: Returns same as Get with empty body
- Options: Returns “Get, Post, Head, Options”
-
/Books
- Get: Search/List of books, return body list of books matching the search/list criteria with headers containing the paging information
- Post: Create a new book for author with Id returns created Book
- Put: Not Supported return “403 Forbidden” error
- Delete: Not Supported return “403 Forbidden” error
- Patch: Not Supported return “403 Forbidden” error
- Head: returns same as Get with empty body
- Options: returns “Get, Post, Head, Options”
-
/Books/{id}
- Get: Returns the book with ID
- Post: Not Supported return “403 Forbidden” error
- Put: update the book
- Delete: Deletes the book
- Patch: Not Supported return “403 Forbidden” error
- Head: Not Supported return “403 Forbidden” error
- Options: returns “Get, Put, Delete, Options”
To be continued…