{"id":22350122,"url":"https://github.com/gcp-development/quarkus-template-api","last_synced_at":"2026-04-18T17:01:42.980Z","repository":{"id":63344448,"uuid":"566894389","full_name":"gcp-development/quarkus-template-api","owner":"gcp-development","description":"Quarkus Template Rest API","archived":false,"fork":false,"pushed_at":"2023-01-30T15:18:57.000Z","size":524,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-26T11:32:13.716Z","etag":null,"topics":["kubernetes","microservices","openapi","quarkus","rest-api","swagger","swagger-ui"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gcp-development.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-11-16T16:32:41.000Z","updated_at":"2023-01-30T15:25:54.000Z","dependencies_parsed_at":"2023-02-16T08:46:20.712Z","dependency_job_id":null,"html_url":"https://github.com/gcp-development/quarkus-template-api","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/gcp-development/quarkus-template-api","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gcp-development%2Fquarkus-template-api","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gcp-development%2Fquarkus-template-api/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gcp-development%2Fquarkus-template-api/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gcp-development%2Fquarkus-template-api/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gcp-development","download_url":"https://codeload.github.com/gcp-development/quarkus-template-api/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gcp-development%2Fquarkus-template-api/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31976805,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-18T16:27:12.723Z","status":"ssl_error","status_checked_at":"2026-04-18T16:27:11.140Z","response_time":103,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["kubernetes","microservices","openapi","quarkus","rest-api","swagger","swagger-ui"],"created_at":"2024-12-04T11:10:17.798Z","updated_at":"2026-04-18T17:01:42.961Z","avatar_url":"https://github.com/gcp-development.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Quarkus Template Rest API\n\n## Motivation\n\n[Microservices](https://martinfowler.com/articles/microservices.html) plays an essential part of my work since 2008. Together with [Kubernetes](https://kubernetes.io/docs/home/) (around 2014) , it’s possible to scale each service independently for granular control of workload performance. Though the Microservice Architecture and Kubernetes we have a significant number of native capacity-scaling approaches, that allows us to address complex problems in a very cost effective way. \nThe Kubernetes landscape is not completed without [Anthos](https://cloud.google.com/anthos/docs/concepts/overview), due the fact that is currently(2022/11) the only product that manages multiple clusters, which makes it the cherry on top of the cake.(Obviously these scenarios with Anthos should be considered only for organizations of a certain dimension or complex Kubernetes workloads across different clouds providers.)\n\nWhen developing an API strategy, one of the key rules is \u003cb\u003estart small think big\u003c/b\u003e. Meaning we normally start with a couple of Rest APIs with few users and after one year we have an \"non planned\" API marketplace (API marketplace is a user-friendly public hub where API providers can publish APIs for developers and partners to consume).\n\nKnowing how to use Kubernetes and Microservice Architecture we are able in a controlled and cost effective way scale-up/down, to match our business demand without breaking the piggy bank. With this type of approach we can planned a [series funding round](https://www.seedready.org/resources/startup-funding-beginners-guide/) based in a flexible digital landscape at a reasonable cost.\n\n## Table of Contents\u003cbr\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"https://github.com/gcp-development/quarkus-template-api/blob/main/README.md#quarkus\" target=\"_self\"\u003eQuarkus\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://github.com/gcp-development/quarkus-template-api/blob/main/README.md#proof-of-conceptrest-api\" target=\"_self\"\u003eProof of Concept(Rest API)\u003c/a\u003e\u003c/li\u003e\n   \u003cul\u003e\n      \u003cli\u003e\u003ca href=\"https://github.com/gcp-development/quarkus-template-api/blob/main/README.md#source-code\" target=\"_self\"\u003eSource Code\u003c/a\u003e\u003c/li\u003e\n      \u003cli\u003e\u003ca href=\"https://github.com/gcp-development/quarkus-template-api/blob/main/README.md#docker-image\" target=\"_self\"\u003eDocker image\u003c/a\u003e\u003c/li\u003e\n      \u003cli\u003e\u003ca href=\"https://github.com/gcp-development/quarkus-template-api/blob/main/README.md#testing-the-rest-api-with-postman-and-intellij-community\" target=\"_self\"\u003eTesting the Rest API with Postman and Intellij Community\u003c/a\u003e\u003c/li\u003e\n   \u003c/ul\u003e\n\u003cli\u003e\u003ca href=\"https://github.com/gcp-development/quarkus-template-api/blob/main/README.md#restful-api-design-guidelines\" target=\"_self\"\u003eRestful API design guidelines\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003chr\u003e\n\n## Quarkus\n\n[What is Quarkus?](https://quarkus.io/about/)\u003cbr\u003e\nQuarkus is a Kubernetes-native Java framework tailored for [GraalVM](https://www.graalvm.org/) and [HotSpot](https://wiki.openjdk.org/display/HotSpot), crafted from best-of-breed Java libraries and standards.\n\nWhy Quarkus?\n\u003cul\u003e\n\u003cli\u003eQuarkus was designed around \u003ca href=\"https://quarkus.io/kubernetes-native/\" target=\"_blank\"\u003eKubernetes-native\u003c/a\u003e philosophies, optimizing for low memory usage and fast startup times.\u003c/li\u003e\n\u003cli\u003eQuarkus, at its core, is based on a fully reactive and non-blocking architecture powered by \u003ca href=\"https://vertx.io/\" target=\"_blank\"\u003eEclipse Vert.x\u003c/a\u003e.\u003c/li\u003e\n\u003c/ul\u003e\n\nEssential Guides:\u003cbr\u003e\n\u003cul\u003e\n   \u003cli\u003e\u003ca href=\"https://quarkus.io/guides/getting-started-testing\" target=\"_blank\"\u003eTesting Your Application\u003c/a\u003e\u003c/li\u003e\n   \u003cli\u003e\u003ca href=\"https://quarkus.io/guides/deploying-to-kubernetes\" target=\"_blank\"\u003eDeploying to kubernetes\u003c/a\u003e\u003c/li\u003e\n   \u003cli\u003e\u003ca href=\"https://quarkus.io/guides/building-native-image\" target=\"_blank\"\u003eBuilding an application into a native image\u003c/a\u003e\u003c/li\u003e\n   \u003cli\u003e\u003ca href=\"https://quarkus.io/guides/kafka-dev-services\" target=\"_blank\"\u003eKafka dev services\u003c/a\u003e\u003c/li\u003e\n   \u003cli\u003e\u003ca href=\"https://quarkus.io/guides/datasource#dev-services-configuration-free-databases\" target=\"_blank\"\u003eDev Services for databases\u003c/a\u003e\u003c/li\u003e\n   \u003cli\u003e\u003ca href=\"https://quarkus.io/guides/redis-dev-services\" target=\"_blank\"\u003eRedis dev services\u003c/a\u003e\u003c/li\u003e\n   \u003cli\u003e\u003ca href=\"https://quarkus.io/guides/amqp-dev-services\" target=\"_blank\"\u003eAMQP dev services\u003c/a\u003e\u003c/li\u003e\n   \u003cli\u003e\u003ca href=\"https://quarkus.io/guides/security-openid-connect-dev-services\" target=\"_blank\"\u003eDev Services for OpenID Connect\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\n\u003chr\u003e\n\n## Proof of Concept(Rest API)\n\n#### Source Code\n\nThis proof of concept(PoC) developed creates an Rest API associated to an [container](https://kubernetes.io/docs/reference/glossary/?fundamental=true#term-container) to be deployed to a Kubernetes [cluster](https://kubernetes.io/docs/reference/glossary/?fundamental=true#term-cluster). This code was develop using [Intellij Community](https://www.jetbrains.com/idea/download/#section=linux) with the [quarkus-tools](https://plugins.jetbrains.com/plugin/13234-quarkus-tools) plugin in a [Ubuntu 22.04.1 LTS (Jammy Jellyfish)](https://releases.ubuntu.com/22.04/).\n\n![image](https://user-images.githubusercontent.com/76512851/203339810-c1aaca7b-c54d-4e2a-87c9-eef016d42d12.png)\n\n#### Execute the project\n\nExecute the project and right-click anywhere inside of the the maven run tile.\n\n![image](https://user-images.githubusercontent.com/76512851/203345483-4e655ec7-b310-482e-a8d6-186a951cda5d.png)\n\n\n#### Open the Application\n\n![image](https://user-images.githubusercontent.com/76512851/203411672-6b9eae1d-2712-420b-a8a5-45423ebc55e7.png)\n\n#### OpenAPI specification\n\n```bash\n{\n  \"openapi\" : \"3.0.3\",\n  \"info\" : {\n    \"title\" : \"quarkus-template-api API\",\n    \"version\" : \"1.0.0-SNAPSHOT\"\n  },\n  \"paths\" : {\n    \"/books\" : {\n      \"get\" : {\n        \"tags\" : [ \"Book Resource\" ],\n        \"responses\" : {\n          \"200\" : {\n            \"description\" : \"OK\"\n          }\n        }\n      },\n      \"post\" : {\n        \"tags\" : [ \"Book Resource\" ],\n        \"requestBody\" : {\n          \"content\" : {\n            \"application/json\" : {\n              \"schema\" : {\n                \"$ref\" : \"#/components/schemas/Book\"\n              }\n            }\n          }\n        },\n        \"responses\" : {\n          \"200\" : {\n            \"description\" : \"OK\"\n          }\n        }\n      },\n      \"delete\" : {\n        \"tags\" : [ \"Book Resource\" ],\n        \"responses\" : {\n          \"200\" : {\n            \"description\" : \"OK\"\n          }\n        }\n      }\n    },\n    \"/books/bulk\" : {\n      \"post\" : {\n        \"tags\" : [ \"Book Resource\" ],\n        \"requestBody\" : {\n          \"content\" : {\n            \"application/json\" : {\n              \"schema\" : {\n                \"type\" : \"array\",\n                \"items\" : {\n                  \"$ref\" : \"#/components/schemas/Book\"\n                }\n              }\n            }\n          }\n        },\n        \"responses\" : {\n          \"200\" : {\n            \"description\" : \"OK\"\n          }\n        }\n      }\n    },\n    \"/books/enhancedmediatype\" : {\n      \"get\" : {\n        \"tags\" : [ \"Book Resource\" ],\n        \"responses\" : {\n          \"200\" : {\n            \"description\" : \"OK\"\n          }\n        }\n      }\n    },\n    \"/books/{key}\" : {\n      \"get\" : {\n        \"tags\" : [ \"Book Resource\" ],\n        \"parameters\" : [ {\n          \"name\" : \"key\",\n          \"in\" : \"path\",\n          \"required\" : true,\n          \"schema\" : {\n            \"format\" : \"int32\",\n            \"type\" : \"integer\"\n          }\n        } ],\n        \"responses\" : {\n          \"200\" : {\n            \"description\" : \"OK\"\n          }\n        }\n      },\n      \"put\" : {\n        \"tags\" : [ \"Book Resource\" ],\n        \"parameters\" : [ {\n          \"name\" : \"key\",\n          \"in\" : \"path\",\n          \"required\" : true,\n          \"schema\" : {\n            \"format\" : \"int32\",\n            \"type\" : \"integer\"\n          }\n        } ],\n        \"requestBody\" : {\n          \"content\" : {\n            \"application/json\" : {\n              \"schema\" : {\n                \"$ref\" : \"#/components/schemas/Book\"\n              }\n            }\n          }\n        },\n        \"responses\" : {\n          \"200\" : {\n            \"description\" : \"OK\"\n          }\n        }\n      },\n      \"delete\" : {\n        \"tags\" : [ \"Book Resource\" ],\n        \"parameters\" : [ {\n          \"name\" : \"key\",\n          \"in\" : \"path\",\n          \"required\" : true,\n          \"schema\" : {\n            \"format\" : \"int32\",\n            \"type\" : \"integer\"\n          }\n        } ],\n        \"responses\" : {\n          \"200\" : {\n            \"description\" : \"OK\"\n          }\n        }\n      }\n    }\n  },\n  \"components\" : {\n    \"schemas\" : {\n      \"Book\" : {\n        \"type\" : \"object\",\n        \"properties\" : {\n          \"id\" : {\n            \"format\" : \"int32\",\n            \"type\" : \"integer\"\n          },\n          \"title\" : {\n            \"type\" : \"string\"\n          },\n          \"author\" : {\n            \"type\" : \"string\"\n          }\n        }\n      }\n    }\n  }\n}\n```\n\n#### Open the Dev UI\n\nThis screen will give us an overview of our Rest API developed.\n\n![image](https://user-images.githubusercontent.com/76512851/203379033-261e1f67-8e4c-4420-88f3-012f1f36a64d.png)\n\nFor instance verify the unit tests result.\n\n![image](https://user-images.githubusercontent.com/76512851/203348320-0d9963bd-5e3a-4b6e-85b1-9863f877d768.png)\n\nTest Results\n\n![image](https://user-images.githubusercontent.com/76512851/203348604-f52e2e19-6148-4aea-8218-226dde00ee1b.png)\n\nFor instance open the swagger-ui.\n\n![image](https://user-images.githubusercontent.com/76512851/203380172-f02f0510-c03f-417b-bc3c-601b8d333a19.png)\n\nSwagger-ui\n\n![image](https://user-images.githubusercontent.com/76512851/203380391-11b0dbfe-7300-4600-a059-d381ff674d49.png)\n\nTry it out\n\n![image](https://user-images.githubusercontent.com/76512851/203405128-08f29d61-9d31-481f-b768-f8f452c69a50.png)\n\n\u003chr\u003e\n\n#### Docker Image\n\nQuarkus adopts the container first approach. This approach is optimized for low memory usage and fast startup times in areas like build time metadata processing and reduction in reflection usage. \n\n\u003cb\u003eQuarkus application load steps.\u003c/b\u003e\n\n![image](https://user-images.githubusercontent.com/76512851/203414467-6da0897d-2f36-4307-a0dc-17928bd8ec56.png)\n\nNote:Image from Quarkus: [The Black Swan of Java?](https://www.jug.ch/events/slides/200430_jugch_Quarkus_-_Black_Swan_of_Java.pdf)\n\n[.dockerignore](https://docs.docker.com/engine/reference/builder/#dockerignore-file)\n```bash\ntarget\n```\n\n[Dockerfile](https://docs.docker.com/engine/reference/builder/)\n\n```bash\nFROM quay.io/quarkus/quarkus-micro-image:2.0\nWORKDIR /work/\nRUN chown 1001 /work \\\n    \u0026\u0026 chmod \"g+rwX\" /work \\\n    \u0026\u0026 chown 1001:root /work\nCOPY --chown=1001:root target/*-runner /work/application\n\nEXPOSE 8080\nUSER 1001\n\nCMD [\"./application\", \"-Dquarkus.http.host=0.0.0.0\"]\n```\nNote: [Parent-image](https://docs.docker.com/glossary/#parent-image):[quarkus-micro-image](https://quay.io/repository/quarkus/quarkus-micro-image?tab=tags\u0026tag=2.0).\n\n\nBuild the docker image.\n\n```bash\n./mvnw package -Pnative\ndocker build -f src/main/docker/Dockerfile.native.dev -t quarkus-template-api:1.0 .\n```\n\n![image](https://user-images.githubusercontent.com/76512851/203319182-e96feeb8-1b35-4b97-91a1-9fb80ebee0e6.png)\n\n\nTest the docker image.\n```bash\ndocker run -i --rm -p 8080:8080 quarkus-template-api:1.0\n```\n\n![image](https://user-images.githubusercontent.com/76512851/203319623-0ee42cb4-99ae-4703-9dba-a0237392c9b6.png)\n\nPush the image to [hub.docker](https://hub.docker.com/)\n\n```bash\ndocker tag quarkus-template-api:1.0 {hub.docker}/quarkus-template-api:1.0\ndocker push {hub.docker}/quarkus-template-api:1.0\n```\n\n![image](https://user-images.githubusercontent.com/76512851/203326130-e2f5e0c0-a3e1-46b7-9c12-d02e771eb0a0.png)\n\n\u003chr\u003e\n\n### Testing the Rest API with Postman and Intellij Community\n\nThis is a small test done with [Postman](https://www.postman.com/downloads/) and [Intellij Community](https://www.jetbrains.com/idea/download/#section=linux).\n\n![image](https://user-images.githubusercontent.com/76512851/202681293-33dd0567-6c1b-4554-ac8c-d11f8c7fc9fd.png)\n\n### Add one record.\n\nURL address\n\n```bash\nhttp://localhost:8080/books\n```\n\nContent-Type Header\n```bash\napplication/json\n```\n\nAccept Header\n```bash\napplication/json\n```\n\n![image](https://user-images.githubusercontent.com/76512851/202450475-c15ea0b1-4174-4078-9e8a-ed36d63d8af1.png)\n\nBody\n```bash\n{\"id\": 0,\"title\":\"Moby Dick\",\"author\":\"Herman Melville\"}\n```\n\n![image](https://user-images.githubusercontent.com/76512851/202452756-8684d334-4d49-4a04-9431-c00a2bda3d99.png)\n\n### Add records in bulk.\n\nURL address\n\n```bash\nhttp://localhost:8080/books/bulk\n```\n\nContent-Type Header\n```bash\napplication/json\n```\n\nAccept Header\n```bash\napplication/json\n```\n\nBody\n```bash\n[\n{\"id\": 0,\"title\":\"Raven\",\"author\":\"John Jacobs\"},\n{\"id\": 0,\"title\":\"In Cold Blood\",\"author\":\"Truman Capote\"},\n{\"id\": 0,\"title\":\"Brave New World\",\"author\":\"Aldous Huxley\"},\n{\"id\": 0,\"title\":\"Nineteen Eighty-Four\",\"author\":\"George Orwell\"},\n{\"id\": 0,\"title\":\"The Art of War\",\"author\":\"Sun-Tzu\"}\n]\n```\n\n![image](https://user-images.githubusercontent.com/76512851/202676095-49073b15-25d4-4270-a5f3-d233cadaabbb.png)\n\n### Read all records.\n\nURL address\n\n```bash\nhttp://localhost:8080/books\n```\n\nContent-Type Header\n```bash\napplication/json\n```\n\nAccept Header\n```bash\napplication/json\n```\n\n![image](https://user-images.githubusercontent.com/76512851/202724984-72780494-c3b8-4cf8-b363-81f3d634e4cb.png)\n\n\n### Search for one record.\n\nURL address\n\n```bash\nhttp://localhost:8080/books/2\n```\n\nContent-Type Header\n```bash\napplication/json\n```\n\nAccept Header\n```bash\napplication/json\n```\n\n![image](https://user-images.githubusercontent.com/76512851/202677031-05aad6dc-6f1b-4664-a763-ad754f0aa35c.png)\n\n### Update a record.\n\nURL address\n\n```bash\nhttp://localhost:8080/books/2\n```\n\nContent-Type Header\n```bash\napplication/json\n```\n\nAccept Header\n```bash\napplication/json\n```\n\n![image](https://user-images.githubusercontent.com/76512851/202678440-d58209a3-f796-49a3-8163-4727e7942c73.png)\n\n### Delete a record.\n\nURL address\n\n```bash\nhttp://localhost:8080/books/2\n```\n\n![image](https://user-images.githubusercontent.com/76512851/202679454-dccff9a9-59e0-4609-8b29-320d766de511.png)\n\n### Delete all records.\n\nURL address\n\n```bash\nhttp://localhost:8080/books/\n```\n\n![image](https://user-images.githubusercontent.com/76512851/202679874-0489a45c-8313-482c-80b6-1634cbf7f25c.png)\n\n### API versioning.\n\nURL address\n\n```bash\nhttp://localhost:8080/books/enhancedmediatype\n```\n\nContent-Type Header for version 1\n```bash\napplication/org.microservice.api.v1.book+json;qs=0.5\n```\n\nAccept Header for version 1\n```bash\napplication/org.microservice.api.v1.book+json;qs=0.5\n```\n\n![image](https://user-images.githubusercontent.com/76512851/202695072-6aeee6fa-233a-477d-b6bd-4c6caf070138.png)\n\nURL address\n\n```bash\nhttp://localhost:8080/books/enhancedmediatype\n```\n\nContent-Type Header for version 2\n```bash\napplication/org.microservice.api.v2.book+json;qs=0.9\n```\n\nAccept Header for version 2\n```bash\napplication/org.microservice.api.v2.book+json;qs=0.9\n```\n\n![image](https://user-images.githubusercontent.com/76512851/202695995-662d87e1-df75-4662-9ab2-959e267dfcf9.png)\n\n\u003chr\u003e\n\n## Restful API design guidelines\n\nDesign First\n\n![image](https://user-images.githubusercontent.com/76512851/203150314-78105b67-7ae9-4cf8-a32e-0806b97611c4.png)\n\nDesign-First: This approach fundamentally means any API effort — whether one or many in a program — starts with a design process. In this model, APIs are defined in an iterative way that both humans and computers can understand — before any code is ever written. The goal is that every team speaks the same language, and every tool they use leverages the same API design. The crucial difference here compared to [others approaches](https://swagger.io/resources/articles/adopting-an-api-first-approach/) is that the design process is what ensures all stakeholders are involved, and their needs are satisfied in the creation.\n\n\u003ch4\u003e1) Use nouns for resource identification.\u003c/h4\u003e\n   For an easy understanding we should use this structure for every resource:\u003cbr\u003e\n\u003cul\u003e\n   \u003cli\u003eGET - /orders - Returns a list of orders.\u003c/li\u003e\n   \u003cli\u003eGET - orders/59 - Returns a specific order, with the id 59.\u003c/li\u003e\n   \u003cli\u003ePOST - /orders - Create a new order.\u003c/li\u003e\n   \u003cli\u003ePUT - /orders/59 - Updates a specific order, with the id 59.\u003c/li\u003e\n   \u003cli\u003eDELETE - /orders/59 - Deletes a specific order, with the id 59.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch4\u003e2) Use proper HTTP headers for serialization formats.\u003c/h4\u003e\nBoth client and server, need to know which format is used for the communication. The format has to be specified in the HTTP-Header.\u003cbr\u003e\n\u003cul\u003e\n   \u003cli\u003eContent-Type defines the request format.\u003c/li\u003e\n   \u003cli\u003eAccept defines a list of acceptable response formats.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch4\u003e3) GET method and query parameters should not alter the state.\u003c/h4\u003e\nUse PUT, POST and DELETE methods instead of the GET method to alter the state. Do not use GET for state changes. GET should be idempotent. (Idempotent-property of certain operations whereby they can be applied multiple times without changing the result beyond the initial application.)\n\n\u003ch4\u003e4) Use sub-resources for relations.\u003c/h4\u003e\nIf a resource is related to another resource using subresources.\n\u003cul\u003e\n   \u003cli\u003eGET - /orders/49/products/ Returns a list of products for order 49.\u003c/li\u003e\n   \u003cli\u003eGET - /orders/49/products/2 Returns product id 2 for order 49.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch4\u003e5) Use proper HTTP methods (verbs).\u003c/h4\u003e\nHTTP methods used by most RESTful web APIs are:\u003cbr\u003e\n\u003cul\u003e\n   \u003cli\u003eGET - retrieves a representation of the resource at the specified URI. The body of the response message contains the details of the requested resource.\u003c/li\u003e\n   \u003cli\u003ePOST - creates a new resource at the specified URI. The body of the request message provides the details of the new resource. Note that POST can also be used to trigger operations that don't actually create resources.\u003c/li\u003e\n   \u003cli\u003ePUT - either creates or replaces the resource at the specified URI. The body of the request message specifies the resource to be created or updated.\u003c/li\u003e\n   \u003cli\u003ePATCH  - performs a partial update of a resource. The request body specifies the set of changes to apply to the resource.\u003c/li\u003e\n   \u003cli\u003eDELETE - removes the resource at the specified URI.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch4\u003e6) HTTP response status codes.\u003c/h4\u003e\nWhen the client raises a request to the server through an API, the client should know the feedback, whether it failed, passed or the request was wrong.\nThe following are the important categorization of HTTP codes:\u003cbr\u003e\n\u003cul\u003e\n   \u003cli\u003e2xx (Success category) These status codes represent that the requested action was received and successfully processed by the server.\u003c/li\u003e\n   \u003cul\u003e\n      \u003cli\u003e200 Ok The standard HTTP response representing success for GET, PUT or POST.\u003c/li\u003e\n      \u003cli\u003e201 Created This status code should be returned whenever the new instance is created. E.g on creating a new instance, using POST method, should always return 201 status code.\u003c/li\u003e\n      \u003cli\u003e204 No Content represents the request is successfully processed but has not returned any content.DELETE can be a good example of this.\u003c/li\u003e\n   \u003c/ul\u003e\n   \u003cli\u003e3xx (Redirection Category)\u003c/li\u003e\n   \u003cul\u003e\n      \u003cli\u003e304 Not Modified indicates that the client has the response already in its cache. And hence there is no need to transfer the same data again.\u003c/li\u003e\n   \u003c/ul\u003e\n   \u003cli\u003e4xx (Client Error Category) These status codes represent that the client has raised a faulty request.\u003c/li\u003e\n   \u003cul\u003e\n      \u003cli\u003e400 Bad Request indicates that the request by the client was not processed, as the server could not understand what the client is asking for.\u003c/li\u003e\n      \u003cli\u003e401 Unauthorized indicates that the client is not allowed to access resources, and should re-request with the required credentials.\u003c/li\u003e\n      \u003cli\u003e403 Forbidden indicates that the request is valid and the client is authenticated, but the client is not allowed access the page or resource for any reason.\u003c/li\u003e\n      \u003cli\u003e404 Not Found indicates that the requested resource is not available now.\u003c/li\u003e\n      \u003cli\u003e410 Gone indicates that the requested resource is no longer available which has been intentionally moved.\u003c/li\u003e\n   \u003c/ul\u003e\n   \u003cli\u003e5xx (Server Error Category)\u003c/li\u003e\n   \u003cul\u003e\n      \u003cli\u003e500 Internal Server Error indicates that the request is valid, but the server is totally confused and the server is asked to serve some unexpected condition.\u003c/li\u003e\n      \u003cli\u003e503 Service Unavailable indicates that the server is down or unavailable to receive and process the request. Mostly if the server is undergoing maintenance.\u003c/li\u003e\n   \u003c/ul\u003e\n \u003c/ul\u003e\n \n\u003ch4\u003e7) Field name casing convention.\u003c/h4\u003e\n\n[camelCase](https://web.archive.org/web/20080411055228/http://www2.tech.purdue.edu/cit/Courses/CPT355/C_Sharp_Coding_Standards_and_Guidelines.asp) we need to make sure it is consistent across the application.\n\n\u003ch4\u003e8) Searching, sorting,filtering and pagination.\u003c/h4\u003e\nAll of these actions are simply the query on one dataset. There will be no new set of APIs to handle these actions. We need to append the query params with the GET method API.\n\u003cul\u003e\n   \u003cli\u003e Sorting - In case, the client wants to get the sorted list of orders, the GET /ordersendpoint should accept multiple sort params in the query. E.g GET /orders?sort=rank_asc would sort the orders by its rank in ascending order.\u003c/li\u003e\n   \u003cli\u003eFiltering - For filtering the dataset, we can pass various options through query params. E.g GET /orders?category=urgent\u0026location=spain would filter the orders list data with the order category of urgent and where the location is Spain.\u003c/li\u003e\n   \u003cli\u003eSearching - When searching for the orders name in orders list the API endpoint should be GET /orders?search=special.\u003c/li\u003e\n   \u003cli\u003ePagination - When the dataset is too large, we divide the data set into smaller chunks, which helps in improving the performance and is easier to handle the response. Eg. GET /orders?page=10 means get the list of orders on 10th page.\u003c/li\u003e\n\u003c/ul\u003e\n\n\u003ch4\u003e9) Versioning.\u003c/h4\u003e\nThe API Version is mandatory and we should not release an unversioned API. Use a simple ordinal number and avoid dot notation such as 1.2.\nWe are using the URL for the API versioning starting with the letter \"v\".\n\n\u003ch4\u003e10) Provide link for navigating through your API(HATEOAS)\u003c/h4\u003e\nHypermedia as the Engine of Application State is a principle that hypertext links should be used to create a better navigation through the API.\nA hypermedia-driven site provides information to navigate the site’s REST interfaces dynamically by including hypermedia links with the responses.\n\nExample:\n\n```bash\n{\n    \"id\": \"1\",\n    \"name\": \"Coffee Pot\",\n    \"links\": [ {\n        \"rel\": \"self\",\n        \"href\": \"http://localhost:8080/product/1\"\n    } ]\n}\n```\n\nThis response not only has the product’s name but includes the self-linking URL where that resource is located.\nrel means relationship. In this case, it’s a self-referencing hyperlink. For example, an order might have a “rel”:”customer” relationship, linking the order to its customer.\nhref is a complete URL that uniquely defines the resource.\n\n\u003ch4\u003e11) Handling ERROR JSON.\u003c/h4\u003e\nWe should always return the error message in its own set of field. A JSON error body should provide a few things for the developer – a useful error message, a unique error code and possibly a detailed description.\n\nExample:\n\n```bash\n{\n   \"code\": 666,\n   \"message\" : \"java.lang.OutOfMemoryError: Java heap space\",\n   \"description\" : \"You should use .net core.... :)\"\n}\n```\n\n\u003ch4\u003e12) How to create a Rest API URL\u003c/h4\u003e\nWe should use the following formats for the URL.\u003cbr\u003e\n\u003cul\u003e\n   \u003cli\u003ehttps://{Domain name (:Port number)}/{A value indicating REST API}/{API version}/{path for identifying a resource}\u003c/li\u003e\n   \u003cli\u003ehttps://{Domain name indicating REST API(:Port number)}/{API version}/{path for identifying a resource}\u003c/li\u003e\n\u003c/ul\u003e\n\nExamples:\n\n```bash\nhttps://org.com/api/v1/orders/43\nhttps://api.org.com/v1/orders/89\n```\n\n\u003chr\u003e\n\nReferences:\u003cbr\u003e\n[Richardson Maturity Model](https://martinfowler.com/articles/richardsonMaturityModel.html)\u003cbr\u003e\n[REST API Tutorial](https://restfulapi.net/)\u003cbr\u003e\n[Best Practices in API Design](https://swagger.io/blog/api-design/api-design-best-practices/)\u003cbr\u003e\n[Best Practices in API Documentation](https://swagger.io/blog/api-documentation/best-practices-in-api-documentation/)\u003cbr\u003e\n[Quarkus User Stories](https://quarkus.io/blog/tag/user-story/)\u003cbr\u003e\n[Dockerfile Best Practices](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/)\n[Swagger Docs](https://swagger.io/docs/)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgcp-development%2Fquarkus-template-api","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgcp-development%2Fquarkus-template-api","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgcp-development%2Fquarkus-template-api/lists"}