{"id":19136405,"url":"https://github.com/muath-ye/api-design-best-practice","last_synced_at":"2025-05-06T20:09:50.324Z","repository":{"id":52489766,"uuid":"338972881","full_name":"muath-ye/api-design-best-practice","owner":"muath-ye","description":"[English Version] Best practice when you write an API","archived":false,"fork":false,"pushed_at":"2021-02-15T18:31:39.000Z","size":20,"stargazers_count":10,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-19T14:57:25.066Z","etag":null,"topics":["api","laravel","muath-ye"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/muath-ye.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-02-15T05:06:51.000Z","updated_at":"2024-09-13T01:36:29.000Z","dependencies_parsed_at":"2022-09-02T02:10:37.977Z","dependency_job_id":null,"html_url":"https://github.com/muath-ye/api-design-best-practice","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/muath-ye%2Fapi-design-best-practice","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/muath-ye%2Fapi-design-best-practice/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/muath-ye%2Fapi-design-best-practice/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/muath-ye%2Fapi-design-best-practice/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/muath-ye","download_url":"https://codeload.github.com/muath-ye/api-design-best-practice/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252761224,"owners_count":21800125,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["api","laravel","muath-ye"],"created_at":"2024-11-09T06:34:07.163Z","updated_at":"2025-05-06T20:09:50.303Z","avatar_url":"https://github.com/muath-ye.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# Best practice when you write an API\n\n## Some of the points to consider while writing an API:\n\n  - Write for human.\n  \u003e Example: ```/users/{id}/card-number``` instead of ```/users/{id}/pin```.\n\n  - Should use lower case letters.\n  \u003e Example: ```/users/{id}/pending-orders``` instead of ```/users/{id}/Pending_Orders```.\n\n  - Separate words with dashes.\n  \u003e Example: ```/users/{id}/pending-orders``` instead of ```/users/{id}/pending_orders```.\n\n  - Follow the naming pattern similar to the folder structure.\n\n  - Use Hierarchy.\n\n  - Keep in mind while designing an API is maintaining the version number in the API.\n  \n  - No trailing forward slash.\n  \u003e Example: ```/users/{id}/pending-orders``` instead of ```/users/{id}/pending-orders/``` and both should give the same output.\n\n## Naming\n  \n  - Resource should be ```nouns``` not ```verbs```.\n  \u003e Example: /users/{id} instead of /get-user.\n\n  - End-points methods should represent their work.\n  \u003e ```GET /posts``` Retrieves a list of posts.\n  \u003e ```GET /posts/1``` Retrieves a specific post.\n  \u003e ```POST /posts``` Create a new post.\n  \u003e ```PUT /posts/1``` Update all post #1 details.\n  \u003e ```PATCH /posts/1``` Partially update post #1.\n  \u003e ```DELETE /posts/1``` Delete post #1.\n\n## Relationships\n\nIf there is a relationship between resources it can be represented like the following example:\n\nSuppose that each posts has a comments so the end-points will be in the following form:\n\n\u003e ```GET /posts/1/comments``` Retrieves all comments that related to post number #1.\n\n\u003e ```GET /posts/1/comments/5``` Retrieves comment#5 related to post#1\n\n\u003e ```POST /posts/1/comments``` Create a new comment related in post#1\n\n\u003e ```PUT /posts/1/comments/5``` update comment #5 related in post#1\n\n\u003e ```PATCH /posts/1/comments/5``` Partially updates comment #5 related in post#1\n\n\u003e ```DELETE /posts/1/comments/5``` Delete comment #5 related in post#1\n\n## Always use SSL\n\nTo secure your end-points. SSL helps to protect sensitive information such as logins, passwords, account details and cardholders information for e-commerce websites during Internet communication. All data over network will be encrypted.\n\n## Always version your api\n\nBecause end-points may be needed to changes or updated so you need to design your end-points with a version that appeared in URL.\n\n## Result filtering, sorting and searching\n\nIt’s best to keep the base resource URLs as lean as possible. Complex result filters, sorting requirements, and advanced searching\n\nUse a unique query parameter for each field that implements filter, sorting or searching\n\n### Filtering\n\nif you want to get flight which only opened\n\u003e ```/flight?status=open``` so status is a query parameter that implements a filter.\n\n### Sorting\n\nlike filtering a generic parameter sort can be used to describe sorting rules.\n\n\u003e ```GET /flights?sort=priority``` - Retrieves a list of flights in descending order of priority.\n\n\u003e ```GET /flights?sort=priority,created_at``` - Retrieves a list of flights in descending order of priority. Within a specific priority, older flights are ordered first.\n\n### Searching\n\nSometimes basic filters aren’t enough and you need the power of full text search.\n\nThis is a combining between filters and sorting.\n\u003e ```GET /flight?status=open\u0026sort=priority``` Retrieves a list of opened flights in descending order of priority.\n\nExample of search: \n\u003e ```GET /flights?q=return\u0026status=open\u0026sort=priority,created_at``` - Retrieve the highest priority open flights mentioning the word ```return```\n\n## Aliases for common queries\n\nTo make the API experience more pleasant for the average consumer, consider packaging up sets of conditions into easily accessible RESTful paths.\n\nExample of alias:\n\u003e ```GET /flights/recently_opened```\n\n## Prevent abuse\n\nTo prevent abuse you can limit API calls using:\n\n\u003e ```X-Rate-limit``` with status code response\n```429 Too Many Requests```\n\n\u003e ```X-Rate-Limit-Limit``` - The number of allowed requests in the current period\n\n\u003e ```X-Rate-Limit-Remaining``` - The number of remaining requests in the current period\n\n\u003e ```X-Rate-Limit-Reset``` - The number of seconds left in the current period.\n\n## Caching\n\nHTTP provides a built-in caching framework! All you have to do is include some additional outbound response headers and do a little validation when you receive some inbound request headers.\n\nThere are 2 approaches: ETag and Last-Modified\n\n## Errors\n\nJust like an HTML error page shows a useful error message to a visitor, an API should provide a useful error message in a known consumable format.\n\nAPI errors typically break down into 2 types: 400 series status codes for client issues \u0026 500 series status codes for server issues.\n\nJSON error body should provide a few things for the developer - a useful error message, a unique error code (that can be looked up for more details in the docs) and possibly a detailed description.\n\nExample:\n```json\n{\n  \"code\" : 1024,\n  \"message\" : \"Validation Failed\",\n  \"errors\" : [\n    {\n      \"code\" : 5432,\n      \"field\" : \"first_name\",\n      \"message\" : \"First name cannot have fancy characters\"\n    },\n    {\n       \"code\" : 5622,\n       \"field\" : \"password\",\n       \"message\" : \"Password cannot be blank\"\n    }\n  ]\n}\n```\n\n## HTTP Status code\n\nHTTP response status codes indicate whether a specific HTTP request has been successfully completed.\n\nResponses are grouped in five classes:\n\n- Informational responses (100–199)\n- Successful responses (200–299)\n- Redirects (300–399)\n- Client errors (400–499)\n- Server errors (500–599)\n\nThe most common responses:\n- ```200 OK``` - Response to a successful GET, PUT, PATCH or DELETE. Can also be used for a POST that doesn’t result in a creation.\n- ```201 Created``` - Response to a POST that results in a creation. Should be combined with a Location header pointing to the location of the new resource\n- ```204 No Content``` - Response to a successful request that won’t be returning a body (like a DELETE request)\n- ```304 Not Modified``` - Used when HTTP caching headers are in play\n- ```400 Bad Request``` - The request is malformed, such as if the body does not parse\n- ```401 Unauthorized``` - When no or invalid authentication details are provided. Also useful to trigger an auth popup if the API is used from a browser\n- ```403 Forbidden``` - When authentication succeeded but authenticated user doesn’t have access to the resource\n- ```404 Not Found``` - When a non-existent resource is requested\n- ```405 Method Not Allowed``` - When an HTTP method is being requested that isn’t allowed for the authenticated user\n- ```410 Gone``` - Indicates that the resource at this end point is no longer available. Useful as a blanket response for old API versions\n- ```415 Unsupported Media Type``` - If incorrect content type was provided as part of the request\n- ```422 Unprocessable Entity``` - Used for validation errors\n- ```429 Too Many Requests``` - When a request is rejected due to rate limiting","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmuath-ye%2Fapi-design-best-practice","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmuath-ye%2Fapi-design-best-practice","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmuath-ye%2Fapi-design-best-practice/lists"}