pemrograman

02 Membuat API Specification menggunakan OpenAPI

At this stage we will try to create all the API Specifications related to the API that we will create so we need complete documentation using OpenAPI. If you haven’t installed OpenAPI in the repository, try reading the previous article first.

Get Article List

So first we will create this API Article list by adding one API to the OpenAPI documentation that we have previously defined.

{
  "openapi": "3.0.2",
  "info": {
    "title": "Article RESTFul API",
    "version": "1.0"
  },
  "servers": [
    {
      "url": "http://localhost:8080"
    }
  ],
  "paths": {
    "/articles": {
      "get": {
        "description": "List All Articles",
        "summary": "List All Articles",
        "tags": [
          "Article API"
        ],
        "responses": {
          "200": {
            "description": "Success get all articles",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "number"
                    },
                    "status": {
                      "type": "string"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "title": {
                            "type": "string"
                          },
                          "content": {
                            "type": "string"
                          },
                           "created_at": {
                              "type": "string"
                           },
                           "updated_at":{
                              "type": "string"
                           }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

Create Article

Next we will add the Create data article endpoint which will be used to add data to the database.

{
  ...
	...
  "paths": {
    "/articles": {
			...
      "post": {
        "description": "Create new article",
        "summary": "Create New Article",
        "tags": [
          "Article API"
        ],
        "requestBody":{
          "content": {
            "application/json":{
              "schema":{
                "type": "object",
                "properties": {
                  "title": {
                    "type": "string"
                  },
                  "content": {
                    "type": "string"
                  },
                  "created_at": {
                     "type": "string"
                  },
                  "updated_at":{
                     "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success create new article",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "number"
                    },
                    "status": {
                      "type": "string"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "title": {
                            "type": "string"
                          },
                          "content": {
                            "type": "string"
                          },
                           "created_at": {
                              "type": "string"
                           },
                           "updated_at":{
                              "type": "string"
                           }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

Because we use the same response from these two endpoints, we will create a component so that it can be used in each endpoint because it has similar data. You can see the changes below.

{
	"paths": {
		...
		...
	},
	"components": {
    "schemas": {
      "Article": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "title": {
                  "type": "string"
                },
                "content": {
                  "type": "string"
                },
                 "created_at": {
                     "type": "string"
                  },
                  "updated_at":{
                     "type": "string"
                  }
              }
            }
          }
        }
      }
    }
  }
}

Save the component under the paths tag and then remove some of the schema used in each endpoint and change it to this.

{
	"items": {
		"$ref": "#/components/schemas/Article"
	}
}

Get Single Data Article

Followed by creating API Specification documentation for get single data article as below. Because this get data article uses the GET method, we put in the JSON tags that GET.

  "/articles/{article_id}":{
    "get":{
      "description": "Get Single Article",
      "summary": "Get Single Article by ID",
      "tags": [
        "Article API"
      ],
      "parameters": [
        {
          "name": "article_id",
          "in":"path",
          "description": "Article Id"
        }
      ],
      "responses": {
        "200": {
          "description": "Success get article 1",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "code": {
                    "type": "number"
                  },
                  "status": {
                    "type": "string"
                  },
                  "data": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/Article"
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }

Update Article Data

create API Specification documentation for update article data as below. Because the parameters are the same as Get Article, it can be used as below.

  "/articles/{article_id}":{
    "put":{
      "description": "Update Article",
      "summary": "Update Article by ID",
      "tags": [
        "Article API"
      ],
      "parameters": [
        {
          "name": "article_id",
          "in":"path",
          "description": "Article Id"
        }
      ],
      "requestBody":{
          "content": {
            "application/json":{
              "schema":{
                "type": "object",
                "properties": {
                  "title": {
                    "type": "string"
                  },
                  "content": {
                    "type": "string"
                  },
                  "created_at": {
                     "type": "string"
                  },
                  "updated_at":{
                     "type": "string"
                  }
                }
              }
            }
          }
        },
      "responses": {
        "200": {
          "description": "Success update article 1",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "code": {
                    "type": "number"
                  },
                  "status": {
                    "type": "string"
                  },
                  "data": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/Article"
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }

The request body for Create and Update has the same JSON so we will create a new component like this

{
  ...
  "CreatOrUpdateArticle": {
    "type": "object",
    "properties": {
        "title": {
          "type": "string"
        },
        "content": {
          "type": "string"
        }
    }
  },
  ...
}

Then we update the RequestBody of the Create and Update API Specification to this.

{
  "requestBody": {
      "content": {
        "application/json": {
            "schema": {
              "$ref": "#/components/schemas/CreatOrUpdateArticle"
            }
        }
      }
  },
}

Delete Article Data

To create an API Specification to delete Article data, it is the same as Get article data so we can just copy it and change some of the components and methods to DELETE.

{
   "delete": {
      "description": "Delete Article",
      "summary": "Delete Article by ID",
      "tags": [
         "Article API"
      ],
      "parameters": [
         {
            "name": "article_id",
            "in": "path",
            "description": "Article Id"
         }
      ],
      "responses": {
         "200": {
            "description": "Success delete article 1",
            "content": {
               "application/json": {
                  "schema": {
                     "type": "object",
                     "properties": {
                        "code": {
                           "type": "number"
                        },
                        "status": {
                           "type": "string"
                        }
                     }
                  }
               }
            }
         }
      }
   }
}

API Specification Security

We will also add security to the API Specification that we will create. For now, we will keep it simple by creating an additional component like this.

{
  "securitySchemes": {
    "articleAuth": {
      "type": "apiKey",
      "in": "header",
      "name": "X-API-Key",
      "description": "Authentication for Article API"
    }
  }
}

Then in the swager UI, you will see the Auhorize button and if you click it, it will display like this.

Authorize Key Swagger

Then add it to each API Specification endpoint that we have created by adding the component that was created above to be like this.

{
  "security": [
    {
      "ArticleAuth": []
    }
  ]
}

More complete JSON API Specification that we have created is like this

{
   "openapi": "3.0.2",
   "info": {
      "title": "Article RESTFul API",
      "version": "1.0"
   },
   "servers": [
      {
         "url": "http://localhost:8080"
      }
   ],
   "paths": {
      "/articles": {
         "get": {
            "description": "List All Articles",
            "summary": "List All Articles",
            "tags": [
               "Article API"
            ],
            "security": [
               {
                  "ArticleAuth":[]
               }
            ],
            "responses": {
               "200": {
                  "description": "Success get all articles",
                  "content": {
                     "application/json": {
                        "schema": {
                           "type": "object",
                           "properties": {
                              "code": {
                                 "type": "number"
                              },
                              "status": {
                                 "type": "string"
                              },
                              "data": {
                                 "type": "array",
                                 "items": {
                                    "$ref": "#/components/schemas/Article"
                                 }
                              }
                           }
                        }
                     }
                  }
               }
            }
         },
         "post": {
            "description": "Create new article",
            "summary": "Create New Articles",
            "tags": [
               "Article API"
            ],
            "security": [
               {
                  "ArticleAuth":[]
               }
            ],
            "requestBody": {
               "content": {
                  "application/json": {
                     "schema": {
                        "$ref": "#/components/schemas/CreatOrUpdateArticle"
                     }
                  }
               }
            },
            "responses": {
               "200": {
                  "description": "Success create new article",
                  "content": {
                     "application/json": {
                        "schema": {
                           "type": "object",
                           "properties": {
                              "code": {
                                 "type": "number"
                              },
                              "status": {
                                 "type": "string"
                              },
                              "data": {
                                 "type": "array",
                                 "items": {
                                    "$ref": "#/components/schemas/Article"
                                 }
                              }
                           }
                        }
                     }
                  }
               }
            }
         }
      },
      "/articles/{article_id}": {
         "get": {
            "description": "Get Single Article",
            "summary": "Get Single Article by ID",
            "tags": [
               "Article API"
            ],
            "security": [
               {
                  "ArticleAuth":[]
               }
            ],
            "parameters": [
               {
                  "name": "article_id",
                  "in": "path",
                  "description": "Article Id"
               }
            ],
            "responses": {
               "200": {
                  "description": "Success get article 1",
                  "content": {
                     "application/json": {
                        "schema": {
                           "type": "object",
                           "properties": {
                              "code": {
                                 "type": "number"
                              },
                              "status": {
                                 "type": "string"
                              },
                              "data": {
                                 "type": "array",
                                 "items": {
                                    "$ref": "#/components/schemas/Article"
                                 }
                              }
                           }
                        }
                     }
                  }
               }
            }
         },
         "post": {
            "description": "Update Article",
            "summary": "Update Article by ID",
            "tags": [
               "Article API"
            ],
            "security": [
               {
                  "ArticleAuth":[]
               }
            ],
            "parameters": [
               {
                  "name": "article_id",
                  "in": "path",
                  "description": "Article Id"
               }
            ],
            "requestBody": {
               "content": {
                  "application/json": {
                     "schema": {
                        "$ref": "#/components/schemas/CreatOrUpdateArticle"
                     }
                  }
               }
            },
            "responses": {
               "200": {
                  "description": "Success update article 1",
                  "content": {
                     "application/json": {
                        "schema": {
                           "type": "object",
                           "properties": {
                              "code": {
                                 "type": "number"
                              },
                              "status": {
                                 "type": "string"
                              },
                              "data": {
                                 "type": "array",
                                 "items": {
                                    "$ref": "#/components/schemas/Article"
                                 }
                              }
                           }
                        }
                     }
                  }
               }
            }
         },
         "delete": {
            "description": "Delete Article",
            "summary": "Delete Article by ID",
            "tags": [
               "Article API"
            ],
            "security": [
               {
                  "ArticleAuth":[]
               }
            ],
            "parameters": [
               {
                  "name": "article_id",
                  "in": "path",
                  "description": "Article Id"
               }
            ],
            "responses": {
               "200": {
                  "description": "Success delete article 1",
                  "content": {
                     "application/json": {
                        "schema": {
                           "type": "object",
                           "properties": {
                              "code": {
                                 "type": "number"
                              },
                              "status": {
                                 "type": "string"
                              }
                           }
                        }
                     }
                  }
               }
            }
         }
      }
   },
   "components": {
      "securitySchemes": {
         "ArticleAuth":{
            "type": "apiKey",
            "in": "header",
            "name": "X-API-Key",
            "description": "Authentication for Article API"
         }
      },
      "schemas": {
         "CreatOrUpdateArticle": {
            "type": "object",
            "properties": {
               "title": {
                  "type": "string"
               },
               "content": {
                  "type": "string"
               }
            }
         },
         "Article": {
            "type": "object",
            "properties": {
               "id":{
                  "type": "number"
               },
               "title": {
                  "type": "string"
               },
               "content": {
                  "type": "string"
               },
                "created_at": {
                  "type": "string"
               },
               "updated_at":{
                  "type": "string"
               }
            }
         }
      }
   }
}
comments powered by Disqus