{"id":1760,"date":"2020-05-07T18:27:26","date_gmt":"2020-05-07T18:27:26","guid":{"rendered":"https:\/\/readmeprd.wpenginepowered.com\/?p=1760"},"modified":"2024-11-02T17:24:35","modified_gmt":"2024-11-02T22:24:35","slug":"http-api-faux-pas","status":"publish","type":"post","link":"https:\/\/readme.com\/resources\/http-api-faux-pas","title":{"rendered":"6 Faux Pas of HTTP API Design"},"content":{"rendered":"\n<p><\/p>\n\n\n\n<p>HTTP APIs are very loose by definition: there\u2019s no standards body, no API validator and not always someone there to tell you when you may be doing something incorrect. At ReadMe we have lots of experience in building, consuming and viewing APIs created by others. We even have our own open source <a href=\"https:\/\/preview.readme.io\/\">API Explorer<\/a> which is used by all of our projects to try out APIs in the browser.<\/p>\n\n\n\n<p>I asked engineers in the ReadMe team, \u201cWhat are some common issues or pitfalls you see when using APIs?\u201d This is a definitely a non-exhaustive list, but avoiding some of these pitfalls will make your APIs more \u201cstandard,\u201d intuitive, and easy to use. We came up with the following faux pas:<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"1sendingamixtureofqueryparamsandbodyparams\">1. Sending a Mixture of Query Params and Body Params<\/h2>\n\n\n\n<p>When you create an API endpoint you should consider accepting <em>either<\/em> query parameters or body parameters, but not both. Since GET requests can\u2019t have bodies, the best way to pass in parameters and filters is via query string. For POST requests (and other non-idempotent methods) you should prefer bodies.<\/p>\n\n\n\n<p>This is an example of using both query and body params, for a POST request:<\/p>\n\n\n\n<p>&nbsp;<\/p>\n\n\n\n<style>\n.custom-code-block {\n    background-color: #2e3440;\n    color: #d4d4d4;\n    padding: 16px;\n    border-radius: 8px;\n    font-size: 14px;\n    line-height: 1.5;\n    overflow-x: auto;\n}\n\n.custom-code-block .comment {\n    color: #4c566a;\n}\n\n.custom-code-block .keyword {\n    color: #89b3b3;\n    font-weight: bold;\n}\n\n.custom-code-block .variable {\n    color: #89b3b3;\n}\n\n.custom-code-block .string {\n    color: #a3be8c; \n}\n<\/style>\n\n<div class=\"custom-code-block\">\n<pre><code>\n<span class=\"keyword\">POST<\/span> <span class=\"string\">\/employees?position=engineer<\/span> HTTP\/1.1\n<span class=\"variable\">Host<\/span>: api.example.com\n<span class=\"variable\">Accept<\/span>: *\/*\n<span class=\"variable\">Content-Type<\/span>: application\/json\n<span class=\"variable\">Content-Length<\/span>: 25\n\n<span class=\"string\">{<\/span> <span class=\"variable\">\"name\"<\/span>: <span class=\"string\">\"Alice\"<\/span> <span class=\"string\">}<\/span>\n<\/code><\/pre>\n<\/div>\n\n\n\n<p>It should be modified to send both properties via the body:<\/p>\n\n\n\n<style>\n.custom-code-block {\n    background-color: #2e3440;\n    color: #d4d4d4;\n    padding: 16px;\n    border-radius: 8px;\n    font-size: 14px;\n    line-height: 1.5;\n    overflow-x: auto;\n}\n\n.custom-code-block .comment {\n    color: #4c566a;\n}\n\n.custom-code-block .keyword {\n    color: #89b3b3;\n    font-weight: bold;\n}\n\n.custom-code-block .variable {\n    color: #89b3b3;\n}\n\n.custom-code-block .string {\n    color: #a3be8c; \n}\n<\/style>\n\n<div class=\"custom-code-block\">\n<pre><code>\n<span class=\"keyword\">POST<\/span> <span class=\"string\">\/employees<\/span> HTTP\/1.1\n<span class=\"variable\">Host<\/span>: api.example.com\n<span class=\"variable\">Accept<\/span>: *\/*\n<span class=\"variable\">Content-Type<\/span>: application\/json\n<span class=\"variable\">Content-Length<\/span>: 43\n\n<span class=\"string\">{<\/span> <span class=\"variable\">\"name\"<\/span>: <span class=\"string\">\"Alice\"<\/span>, <span class=\"variable\">\"position\"<\/span>: <span class=\"string\">\"engineer\"<\/span> <span class=\"string\">}<\/span>\n<\/code><\/pre>\n<\/div>\n\n\n\n\n<p>Using query strings is fine for filtering, like so:<\/p>\n\n\n\n<style>\n.custom-code-block {\n    background-color: #2e3440;\n    color: #d4d4d4;\n    padding: 16px;\n    border-radius: 8px;\n    font-size: 14px;\n    line-height: 1.5;\n    overflow-x: auto;\n}\n\n.custom-code-block .comment {\n    color: #4c566a;\n}\n\n.custom-code-block .keyword {\n    color: #89b3b3;\n    font-weight: bold;\n}\n\n.custom-code-block .variable {\n    color: #89b3b3;\n}\n\n.custom-code-block .string {\n    color: #a3be8c; \n}\n<\/style>\n\n<div class=\"custom-code-block\">\n<pre><code>\n<span class=\"keyword\">GET<\/span> <span class=\"string\">\/employees?position=engineer<\/span> HTTP\/1.1\n<span class=\"variable\">Host<\/span>: example.com\n<span class=\"variable\">Accept<\/span>: *\/*\n<\/code><\/pre>\n<\/div>\n\n\n\n\n<h2 class=\"wp-block-heading\" id=\"2sendingprivateapikeysinaquerystring\">2. Sending Private API Keys in a Query String<\/h2>\n\n\n\n<p>You should never accept private API keys or passwords in query strings. Servers often print out the whole URL for debugging later in their log files. You don\u2019t want your users\u2019 passwords being stored in plain text on the disk.<\/p>\n\n\n\n<style>\n.custom-code-block {\n    background-color: #2e3440;\n    color: #d4d4d4;\n    padding: 16px;\n    border-radius: 8px;\n    font-size: 14px;\n    line-height: 1.5;\n    overflow-x: auto;\n}\n\n.custom-code-block .comment {\n    color: #4c566a;\n}\n\n.custom-code-block .keyword {\n    color: #89b3b3;\n    font-weight: bold;\n}\n\n.custom-code-block .variable {\n    color: #89b3b3;\n}\n\n.custom-code-block .string {\n    color: #a3be8c; \n}\n<\/style>\n\n<div class=\"custom-code-block\">\n<pre><code>\n<span class=\"keyword\">GET<\/span> <span class=\"string\">\/employees?apiKey=wWERfeUzeA3CuJRKtzfsMTiangi<\/span> HTTP\/1.1\n<span class=\"variable\">Host<\/span>: example.com\n<\/code><\/pre>\n<\/div>\n\n\n\n\n<p>You can switch to using a header for this value to keep your users\u2019 confidential keys and passwords safe:<\/p>\n\n\n\n<style>\n.custom-code-block {\n    background-color: #2e3440;\n    color: #d4d4d4;\n    padding: 16px;\n    border-radius: 8px;\n    font-size: 14px;\n    line-height: 1.5;\n    overflow-x: auto;\n}\n\n.custom-code-block .comment {\n    color: #4c566a;\n}\n\n.custom-code-block .keyword {\n    color: #89b3b3;\n    font-weight: bold;\n}\n\n.custom-code-block .variable {\n    color: #89b3b3;\n}\n\n.custom-code-block .string {\n    color: #a3be8c; \n}\n<\/style>\n\n<div class=\"custom-code-block\">\n<pre><code>\n<span class=\"keyword\">GET<\/span> <span class=\"string\">\/employees<\/span> HTTP\/1.1\n<span class=\"variable\">Host<\/span>: example.com\n<span class=\"variable\">Authorization<\/span>: wWERfeUzeA3CuJRKtzfsMTiangi\n<\/code><\/pre>\n<\/div>\n\n\n\n\n<h2 class=\"wp-block-heading\" id=\"3usingthewrongmethodpostwhenyoumeanputpatch\">3. Using the Wrong Method: POST When You Mean PUT\/PATCH<\/h2>\n\n\n\n<p>HTTP consists of 9 verbs, the most common of which are: GET, POST, PUT, PATCH and DELETE. In REST APIs, each of these roughly translates to the four functions of storage: CRUD.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Action<\/th><th>HTTP Verb<\/th><\/tr><\/thead><tbody><tr><td><strong>C<\/strong>reate<\/td><td>POST<\/td><\/tr><tr><td><strong>R<\/strong>ead<\/td><td>GET<\/td><\/tr><tr><td><strong>U<\/strong>pdate<\/td><td>PUT\/PATCH<\/td><\/tr><tr><td><strong>D<\/strong>elete<\/td><td>DELETE<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>Using the wrong verb is considered bad practice when creating an API, though it\u2019s technically possible. As an API consumer, you would not expect a \u201cRead\u201d operation (GET) to perform a \u201cCreate\u201d (POST). For example: Using GET to \u201cCreate\u201d a new item.<\/p>\n\n\n\n<style>\n.custom-code-block {\n    background-color: #2e3440;\n    color: #d4d4d4;\n    padding: 16px;\n    border-radius: 8px;\n    font-size: 14px;\n    line-height: 1.5;\n    overflow-x: auto;\n}\n\n.custom-code-block .comment {\n    color: #4c566a;\n}\n\n.custom-code-block .keyword {\n    color: #89b3b3;\n    font-weight: bold;\n}\n\n.custom-code-block .variable {\n    color: #89b3b3;\n}\n\n.custom-code-block .string {\n    color: #a3be8c; \n}\n<\/style>\n\n<div class=\"custom-code-block\">\n<pre><code>\n<span class=\"keyword\">GET<\/span> <span class=\"string\">\/employees?name=Alice&amp;position=engineer<\/span> HTTP\/1.1\n<span class=\"variable\">Host<\/span>: example.com\n<\/code><\/pre>\n<\/div>\n\n\n\n\n<p>This should use <strong>POST<\/strong>, with a body.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"4addingverbsinurls\">4. Adding Verbs in URLs<\/h2>\n\n\n\n<p>We\u2019ve seen this one lots of times, where a path contains a verb that should be represented via a method.<\/p>\n\n\n\n<style>\n.custom-code-block {\n    background-color: #2e3440;\n    color: #d4d4d4;\n    padding: 16px;\n    border-radius: 8px;\n    font-size: 14px;\n    line-height: 1.5;\n    overflow-x: auto;\n}\n\n.custom-code-block .comment {\n    color: #4c566a;\n}\n\n.custom-code-block .keyword {\n    color: #89b3b3;\n    font-weight: bold;\n}\n\n.custom-code-block .variable {\n    color: #89b3b3;\n}\n\n.custom-code-block .string {\n    color: #a3be8c; \n}\n<\/style>\n\n<div class=\"custom-code-block\">\n<pre><code>\n<span class=\"keyword\">GET<\/span> <span class=\"string\">\/createEmployee?name=Alice&amp;position=engineer<\/span> HTTP\/1.1\n<span class=\"variable\">Host<\/span>: example.com\n<\/code><\/pre>\n<\/div>\n\n\n\n\n<p>Example of a path containing the verb <code>create<\/code>.<\/p>\n\n\n\n<p>This is similar to using the wrong HTTP method. To correct this, remove the verb from the path and use the correct method. (See table above.)<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"5acceptingmultipletypesofobjectonthesameurl\">5. Accepting Multiple Types of Object on the Same URL<\/h2>\n\n\n\n<p>Sometimes we see developers that create the \u201cone endpoint to rule them all\u2122\u201d\u2014one endpoint that can take a whole host of object shapes. If a path has a very generic noun, like <code>\/entities<\/code> and it accepts lots of different object \u201ctypes,\u201d like this:<\/p>\n\n\n\n<style>\n.custom-code-block {\n    background-color: #2e3440;\n    color: #d4d4d4;\n    padding: 16px;\n    border-radius: 8px;\n    font-size: 14px;\n    line-height: 1.5;\n    overflow-x: auto;\n}\n\n.custom-code-block .comment {\n    color: #4c566a;\n}\n\n.custom-code-block .keyword {\n    color: #89b3b3;\n    font-weight: bold;\n}\n\n.custom-code-block .variable {\n    color: #89b3b3;\n}\n\n.custom-code-block .string {\n    color: #a3be8c; \n}\n<\/style>\n\n<div class=\"custom-code-block\">\n<pre><code>\n<span class=\"string\">{<\/span> <span class=\"variable\">\"type\"<\/span>: <span class=\"string\">\"employee\"<\/span>, <span class=\"variable\">\"name\"<\/span>: <span class=\"string\">\"Alice\"<\/span> <span class=\"string\">}<\/span>\n\n<span class=\"string\">{<\/span> <span class=\"variable\">\"type\"<\/span>: <span class=\"string\">\"widget\"<\/span>, <span class=\"variable\">\"name\"<\/span>: <span class=\"string\">\"Whosit\"<\/span> <span class=\"string\">}<\/span>\n\n<span class=\"string\">{<\/span> <span class=\"variable\">\"type\"<\/span>: <span class=\"string\">\"product\"<\/span>, <span class=\"variable\">\"name\"<\/span>: <span class=\"string\">\"Book\"<\/span> <span class=\"string\">}<\/span>\n<\/code><\/pre>\n<\/div>\n\n\n\n\n<p>It\u2019s better to have a different endpoint for each entity:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\/employees<\/li>\n\n\n\n<li>\/widgets<\/li>\n\n\n\n<li>\/products<\/li>\n<\/ul>\n\n\n\n<p>This is easier for documentation purposes, easier for your debugging and simpler for your users.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"6creatingyourownversionofsomethingwhenaheaderexists\">6. Creating Your Own Version of Something, When a Header Exists<\/h2>\n\n\n\n<p>Often we also see people re-implementing something that already exists as part of the HTTP spec. The main example of this we see regards the Accept\/Content-Type headers.<\/p>\n\n\n\n<p>The <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/HTTP\/Headers\/Accept\">Accept header<\/a> is used by the client to let the API know what content type they would like to get back, the Content-Type header is used by the server to let the client know what type they are actually returning. This process is called <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/HTTP\/Content_negotiation\">content negotiation<\/a>.<\/p>\n\n\n\n<p>We\u2019ve seen unnecessary workarounds for things Accept headers can already handle, such as:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>?format=json<\/code> querystring.<\/li>\n\n\n\n<li><code>.json<\/code> mock extension on the end of the path.<\/li>\n<\/ul>\n\n\n\n<p>There are lots of Accept-* headers that can be utilized for various ways of defining what you as a client expect or prefer:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/HTTP\/Headers\/Accept-Language\">Accept-Language<\/a>\u2014to determine your preferred language response.<\/li>\n\n\n\n<li><a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/HTTP\/Headers\/Accept-Encoding\">Accept-Encoding<\/a>\u2014to determine the preferred encoding of your response.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p>As with every set of rules or best practices, there are times when they are meant to be broken. Typically if you intend for your API to be accessed directly via a browser, you may have to expose things via query string that you (in an ideal world) should do via a header. This is one of the benefits of REST\/HTTP\u2014they allow the flexibility to do whatever you want to do.<\/p>\n\n\n\n<p>Are there any others that you\u2019d add to this list? Am I completely wrong on this? Tweet <a href=\"https:\/\/twitter.com\/readme\">@readme<\/a> with your comments!<\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>HTTP APIs are very loose by definition: there\u2019s no standards body, no API validator and not always someone there to tell you when you may be doing something incorrect. At ReadMe we have lots of experience in building, consuming and viewing APIs created by others. We even have our own open source API Explorer which [&hellip;]<\/p>\n","protected":false},"author":3,"featured_media":1750,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"content-type":"","inline_featured_image":false,"footnotes":""},"categories":[1],"tags":[],"ppma_author":[53],"class_list":["post-1760","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v23.0 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>6 Faux Pas of HTTP API Design - ReadMe: Resource Library<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/readme.com\/resources\/http-api-faux-pas\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"6 Faux Pas of HTTP API Design - ReadMe: Resource Library\" \/>\n<meta property=\"og:description\" content=\"HTTP APIs are very loose by definition: there\u2019s no standards body, no API validator and not always someone there to tell you when you may be doing something incorrect. At ReadMe we have lots of experience in building, consuming and viewing APIs created by others. We even have our own open source API Explorer which [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/readme.com\/resources\/http-api-faux-pas\" \/>\n<meta property=\"og:site_name\" content=\"ReadMe: Resource Library\" \/>\n<meta property=\"article:published_time\" content=\"2020-05-07T18:27:26+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-11-02T22:24:35+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/readme.com\/resources\/wp-content\/uploads\/2020\/05\/blueprints.jpg.png\" \/>\n\t<meta property=\"og:image:width\" content=\"2000\" \/>\n\t<meta property=\"og:image:height\" content=\"631\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Dom Harrington\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Sergey Bezdudnyy\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"4 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/readme.com\/resources\/http-api-faux-pas\",\"url\":\"https:\/\/readme.com\/resources\/http-api-faux-pas\",\"name\":\"6 Faux Pas of HTTP API Design - ReadMe: Resource Library\",\"isPartOf\":{\"@id\":\"https:\/\/readme.com\/resources\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/readme.com\/resources\/http-api-faux-pas#primaryimage\"},\"image\":{\"@id\":\"https:\/\/readme.com\/resources\/http-api-faux-pas#primaryimage\"},\"thumbnailUrl\":\"https:\/\/readme.com\/resources\/wp-content\/uploads\/2020\/05\/blueprints.jpg.png\",\"datePublished\":\"2020-05-07T18:27:26+00:00\",\"dateModified\":\"2024-11-02T22:24:35+00:00\",\"author\":{\"@id\":\"https:\/\/readme.com\/resources\/#\/schema\/person\/5d27caf848984b250c70a69161b76828\"},\"breadcrumb\":{\"@id\":\"https:\/\/readme.com\/resources\/http-api-faux-pas#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/readme.com\/resources\/http-api-faux-pas\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/readme.com\/resources\/http-api-faux-pas#primaryimage\",\"url\":\"https:\/\/readme.com\/resources\/wp-content\/uploads\/2020\/05\/blueprints.jpg.png\",\"contentUrl\":\"https:\/\/readme.com\/resources\/wp-content\/uploads\/2020\/05\/blueprints.jpg.png\",\"width\":2000,\"height\":631},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/readme.com\/resources\/http-api-faux-pas#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/readme.com\/resources\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"6 Faux Pas of HTTP API Design\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/readme.com\/resources\/#website\",\"url\":\"https:\/\/readme.com\/resources\/\",\"name\":\"ReadMe: Resource Library\",\"description\":\"Making API documentation better for everyone\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/readme.com\/resources\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/readme.com\/resources\/#\/schema\/person\/5d27caf848984b250c70a69161b76828\",\"name\":\"Sergey Bezdudnyy\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/readme.com\/resources\/#\/schema\/person\/image\/8a01d0c296bdfcf8b54a6c0c0a94b904\",\"url\":\"https:\/\/readme.com\/resources\/wp-content\/uploads\/2024\/05\/sergey-profile-thumb.webp\",\"contentUrl\":\"https:\/\/readme.com\/resources\/wp-content\/uploads\/2024\/05\/sergey-profile-thumb.webp\",\"caption\":\"Sergey Bezdudnyy\"},\"sameAs\":[\"http:\/\/auq.io\"],\"url\":\"https:\/\/readme.com\/resources\/author\/sergey-auq\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"6 Faux Pas of HTTP API Design - ReadMe: Resource Library","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/readme.com\/resources\/http-api-faux-pas","og_locale":"en_US","og_type":"article","og_title":"6 Faux Pas of HTTP API Design - ReadMe: Resource Library","og_description":"HTTP APIs are very loose by definition: there\u2019s no standards body, no API validator and not always someone there to tell you when you may be doing something incorrect. At ReadMe we have lots of experience in building, consuming and viewing APIs created by others. We even have our own open source API Explorer which [&hellip;]","og_url":"https:\/\/readme.com\/resources\/http-api-faux-pas","og_site_name":"ReadMe: Resource Library","article_published_time":"2020-05-07T18:27:26+00:00","article_modified_time":"2024-11-02T22:24:35+00:00","og_image":[{"width":2000,"height":631,"url":"https:\/\/readme.com\/resources\/wp-content\/uploads\/2020\/05\/blueprints.jpg.png","type":"image\/png"}],"author":"Dom Harrington","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Sergey Bezdudnyy","Est. reading time":"4 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/readme.com\/resources\/http-api-faux-pas","url":"https:\/\/readme.com\/resources\/http-api-faux-pas","name":"6 Faux Pas of HTTP API Design - ReadMe: Resource Library","isPartOf":{"@id":"https:\/\/readme.com\/resources\/#website"},"primaryImageOfPage":{"@id":"https:\/\/readme.com\/resources\/http-api-faux-pas#primaryimage"},"image":{"@id":"https:\/\/readme.com\/resources\/http-api-faux-pas#primaryimage"},"thumbnailUrl":"https:\/\/readme.com\/resources\/wp-content\/uploads\/2020\/05\/blueprints.jpg.png","datePublished":"2020-05-07T18:27:26+00:00","dateModified":"2024-11-02T22:24:35+00:00","author":{"@id":"https:\/\/readme.com\/resources\/#\/schema\/person\/5d27caf848984b250c70a69161b76828"},"breadcrumb":{"@id":"https:\/\/readme.com\/resources\/http-api-faux-pas#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/readme.com\/resources\/http-api-faux-pas"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/readme.com\/resources\/http-api-faux-pas#primaryimage","url":"https:\/\/readme.com\/resources\/wp-content\/uploads\/2020\/05\/blueprints.jpg.png","contentUrl":"https:\/\/readme.com\/resources\/wp-content\/uploads\/2020\/05\/blueprints.jpg.png","width":2000,"height":631},{"@type":"BreadcrumbList","@id":"https:\/\/readme.com\/resources\/http-api-faux-pas#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/readme.com\/resources\/"},{"@type":"ListItem","position":2,"name":"6 Faux Pas of HTTP API Design"}]},{"@type":"WebSite","@id":"https:\/\/readme.com\/resources\/#website","url":"https:\/\/readme.com\/resources\/","name":"ReadMe: Resource Library","description":"Making API documentation better for everyone","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/readme.com\/resources\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/readme.com\/resources\/#\/schema\/person\/5d27caf848984b250c70a69161b76828","name":"Sergey Bezdudnyy","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/readme.com\/resources\/#\/schema\/person\/image\/8a01d0c296bdfcf8b54a6c0c0a94b904","url":"https:\/\/readme.com\/resources\/wp-content\/uploads\/2024\/05\/sergey-profile-thumb.webp","contentUrl":"https:\/\/readme.com\/resources\/wp-content\/uploads\/2024\/05\/sergey-profile-thumb.webp","caption":"Sergey Bezdudnyy"},"sameAs":["http:\/\/auq.io"],"url":"https:\/\/readme.com\/resources\/author\/sergey-auq"}]}},"authors":[{"term_id":53,"user_id":0,"is_guest":1,"slug":"dom-harrington","display_name":"Dom Harrington","avatar_url":{"url":"https:\/\/readme.com\/resources\/wp-content\/uploads\/2024\/06\/1516897618298.jpeg","url2x":"https:\/\/readme.com\/resources\/wp-content\/uploads\/2024\/06\/1516897618298.jpeg"},"first_name":"Dom","last_name":"Harrington","position":"Open Source Engineer","slogan":"","description":"Dom joins the ReadMe team remotely from the UK. He enjoys cooking, long walks in the countryside and playing video games. You\u2019ll likely find him in ReadMe's open source repos frantically writing tests."}],"_links":{"self":[{"href":"https:\/\/readme.com\/resources\/wp-json\/wp\/v2\/posts\/1760","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/readme.com\/resources\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/readme.com\/resources\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/readme.com\/resources\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/readme.com\/resources\/wp-json\/wp\/v2\/comments?post=1760"}],"version-history":[{"count":0,"href":"https:\/\/readme.com\/resources\/wp-json\/wp\/v2\/posts\/1760\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/readme.com\/resources\/wp-json\/wp\/v2\/media\/1750"}],"wp:attachment":[{"href":"https:\/\/readme.com\/resources\/wp-json\/wp\/v2\/media?parent=1760"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/readme.com\/resources\/wp-json\/wp\/v2\/categories?post=1760"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/readme.com\/resources\/wp-json\/wp\/v2\/tags?post=1760"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/readme.com\/resources\/wp-json\/wp\/v2\/ppma_author?post=1760"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}