{"id":12069,"date":"2016-04-20T12:11:02","date_gmt":"2016-04-20T09:11:02","guid":{"rendered":"https:\/\/www.webcodegeeks.com\/?p=12069"},"modified":"2016-04-14T23:38:13","modified_gmt":"2016-04-14T20:38:13","slug":"hypermedia-apis-apache-couchdb","status":"publish","type":"post","link":"https:\/\/www.webcodegeeks.com\/web-development\/hypermedia-apis-apache-couchdb\/","title":{"rendered":"Hypermedia APIs with Apache CouchDB"},"content":{"rendered":"<p>RESTful web services are a thing I love to discuss, build, and use. However, most of them stop short at sending JSON (or XML) back and forth over the wire.<\/p>\n<p>I read the documentation. I write some code with URLs in it and tie my JavaScript, Python, or PHP right into the vendor\u2019s API as it\u2019s currently structured. Any changes to the URLs, and I need to change my code.<\/p>\n<p>What I know about the web doesn\u2019t jive with that. You didn\u2019t read any documentation to find out the URL Codeship uses for this blog post or the blog\u2019s main page or <a href=\"https:\/\/codeship.com\/features\">their services list<\/a> or <a href=\"https:\/\/codeship.com\/pricing\">sign-up page<\/a> either. That\u2019s because HTML, the original web hypermedia format, has these fabulous things called links. JSON and XML don\u2019t.<\/p>\n<p>Let\u2019s take a quick dive into a world of browsable, hypermedia APIs.<\/p>\n<h2>Hypermedia APIs<\/h2>\n<p>Hypermedia APIs are RESTful APIs that use links and media types to avoid some of the chaos of change.<\/p>\n<p>When you visit a web page, you don\u2019t have to read the website\u2019s documentation to know which thing is something you can click or which part of the site can receive data. The web page has all that information in it. You just click. You fill out forms. You browse.<\/p>\n<p>Web browsers take the HTML documents on the web and make them browsable, make them linked, and make the web updatable via forms. Hypermedia APIs offer that same flexibility and opportunity to code.<\/p>\n<h2>Media Type Mastery<\/h2>\n<p>Hypermedia enables browsable APIs by using media types that are defined to contain <a href=\"http:\/\/www.amundsen.com\/blog\/archives\/1109\">hypermedia affordances<\/a> \u2014 essentially, links and forms.<\/p>\n<p>Sadly, sprinkling URLs into some JSON values doesn\u2019t cut it. In essence, <code>application\/json<\/code> is no more a hypermedia, link-containing format than <code>text\/plain<\/code>. They may contain text that is a URL, but they could be anywhere and mean anything. Most importantly, to a JSON parser, they\u2019re just strings.<\/p>\n<p>Hypermedia-enabled media types, however, contain this information within their definitions. Here\u2019s a short list of some JSON-based hypermedia types:<\/p>\n<ul>\n<li><strong>JSON-LD:<\/strong> <code>application\/ld+json<\/code> \u2013 <a href=\"http:\/\/www.w3.org\/TR\/json-ld\">spec<\/a> and <a href=\"http:\/\/www.iana.org\/assignments\/media-types\/application\/ld+json\">registration<\/a><\/li>\n<li><strong>Collection+JSON:<\/strong> <code>application\/collection+json<\/code> \u2013 <a href=\"http:\/\/amundsen.com\/media-types\/collection\/\">spec<\/a> and <a href=\"http:\/\/www.iana.org\/assignments\/media-types\/application\/vnd.collection+json\">registration<\/a><\/li>\n<li><strong>HAL:<\/strong> <code>application\/hal+json<\/code> \u2013 <a href=\"https:\/\/tools.ietf.org\/html\/draft-kelly-json-hal-07\">spec<\/a> and <a href=\"http:\/\/www.iana.org\/assignments\/media-types\/application\/vnd.hal+json\">registration<\/a><\/li>\n<li><strong>Siren:<\/strong> <code>application\/vnd.siren+json<\/code> \u2013 <a href=\"https:\/\/github.com\/kevinswiber\/siren\">spec<\/a> and <a href=\"http:\/\/www.iana.org\/assignments\/media-types\/application\/vnd.siren+json\">registration<\/a><\/li>\n<li><strong>JSON API:<\/strong> <code>application\/vnd.api+json<\/code> \u2013 <a href=\"http:\/\/jsonapi.org\/\">spec<\/a> and <a href=\"http:\/\/www.iana.org\/assignments\/media-types\/application\/vnd.api+json\">registration<\/a><\/li>\n<\/ul>\n<p>Many of these also have more specific extensions or additional vocabularies such as <a href=\"http:\/\/www.hydra-cg.com\/spec\/latest\/core\/\">Hydra<\/a> and <a href=\"http:\/\/schema.org\/docs\/actions.html\">Schema.org Actions<\/a> for JSON-LD. In this case, the media type stays the same, but the contents have additional \u201cmeaning\u201d specific to APIs.<\/p>\n<p>For today, we\u2019re going to run with HAL, the <a href=\"http:\/\/stateless.co\/hal_specification.html\">Hypermedia Application Language<\/a>.<\/p>\n<h2>Apache CouchDB: an HTTP Database<\/h2>\n<p>Apache CouchDB is a NoSQL database that uses JSON and HTTP for its entire API. It\u2019s about as simple and straightforward an API as you\u2019ll find. It\u2019s also a great foundation for building CRUD applications quickly.<\/p>\n<p>However, it lacks any hypermedia affordances, which means if you land at any of its endpoints, you\u2019ll have no idea where to go next or what else may be possible.<\/p>\n<p>The stock API is about as simple as it gets:<\/p>\n<ul>\n<li><code>\/{db}<\/code>\n<ul>\n<li>metadata about the database (size, number of documents, etc)<\/li>\n<li>and the POST endpoint to create JSON documents<\/li>\n<\/ul>\n<\/li>\n<li><code>\/{db}\/{doc}<\/code>\n<ul>\n<li>CRUD (or GPD) for a specific document<\/li>\n<\/ul>\n<\/li>\n<li><code>\/{db}\/_all_docs<\/code>\n<ul>\n<li>the list of documents returned as a JSON array<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>All three of these endpoints return \u201cpure JSON,\u201d typically sent as <code>application\/json<\/code>. Handy, if you know what you\u2019re getting at each endpoint (<em>a.k.a.<\/em>, you\u2019ve read the docs). However, if all you\u2019d been given was the <code>\/{db}<\/code> URL, you\u2019d have no idea how to even find the list of documents within it.<\/p>\n<p>What would this API be like if you didn\u2019t have to read the docs? What would it mean to be able to \u201cbrowse your database\u201d from your code? Let\u2019s hypermedia this thing.<\/p>\n<h2>HyperCouch(DB)<\/h2>\n<p><a href=\"http:\/\/github.com\/bigbluehat\/hypercouch\">HyperCouch<\/a> is an exploration of what CouchDB might be like with a hypermedia API. It wraps the core CouchDB API in various hypermedia formats. It can also be used to hypermedia-enable a CouchDB-based data store such as your next API.<\/p>\n<p>Here are the standard responses to the three endpoints referenced above, along with the new Hypermedia Application Language variations:<\/p>\n<p><code>GET \/{db}<\/code><\/p>\n<pre class=\"brush:php\">{\r\n  \"db_name\":\"hypercouch\",\r\n  \"doc_count\":2,\r\n  \"doc_del_count\":0,\r\n  \"update_seq\":2,\r\n  \"purge_seq\":0,\r\n  \"compact_running\":false,\r\n  \"disk_size\":12393,\r\n  \"data_size\":7377,\r\n  \"instance_start_time\":\"1459778528583743\",\r\n  \"disk_format_version\":6,\r\n  \"committed_update_seq\":2\r\n}<\/pre>\n<p>Just a pure JSON object with some numbers in it.<\/p>\n<p>Now. If you\u2019d asked for that first and wanted to see the contents of the database, where would you go? Don\u2019t go search for the CouchDB docs! Your code can\u2019t.<\/p>\n<p>Let\u2019s take a look at a HAL variation:<\/p>\n<pre class=\"brush:php\">{\r\n  \"db_name\":\"hypercouch\",\r\n  \"doc_count\":2,\r\n  \"doc_del_count\":0,\r\n  \"update_seq\":2,\r\n  \"purge_seq\":0,\r\n  \"compact_running\":false,\r\n  \"disk_size\":12393,\r\n  \"data_size\":7377,\r\n  \"instance_start_time\":\"1459778528583743\",\r\n  \"disk_format_version\":6,\r\n  \"committed_update_seq\":2,\r\n  \"_links\": {\r\n    \"self\": { \"href\": \"\/hypercouch\/\" },\r\n    \"index\": { \"href\": \"\/hypercouch\/_all_docs\" }\r\n  }\r\n}<\/pre>\n<p>HAL+JSON documents are essentially \u201cjust JSON\u201d plus a <code>_links<\/code> object and (optionally) an <code>_embedded<\/code> object (which we\u2019ll look at shortly). The keys within the <code>_links<\/code> object are the <a href=\"http:\/\/tools.ietf.org\/html\/rfc5988#section-1\">link relationship<\/a> of the contained links. The included <code>href<\/code> does what any old <code>href<\/code> does: It contains a URL. In this case, it\u2019s a small additional bit of content that routes the code (or user) to the appropriate endpoint for the primary index within the database.<\/p>\n<p>Let\u2019s look at the other two endpoints.<\/p>\n<p><code>GET \/{db}\/{doc}<\/code><\/p>\n<pre class=\"brush:php\">{\r\n  \"_id\": \"db74fd2411e1a0da283b3f0fc8000074\",\r\n  \"_rev\": \"1-1d7fcf86f6f6ec8d0e63f6de7af5ce81\",\r\n  \"first_name\": \"Benjamin\"\r\n}<\/pre>\n<p>The <code>_id<\/code> and <code>_rev<\/code> values are reserved by CouchDB and record the name and revision identifier of the document.<\/p>\n<pre class=\"brush:php\">{\r\n  \"_id\": \"db74fd2411e1a0da283b3f0fc8000074\",\r\n  \"_rev\": \"...\",\r\n  \"first_name\": \"Benjamin\",\r\n  \"_links\": {\r\n    \"self\": { \"href\": \"\/hypercouch\/db74fd2411e1a0da283b3f0fc8000074\" },\r\n    \"index\": { \"href\": \"\/hypercouch\/_all_docs\" },\r\n    \"collection\": { \"href\": \"\/hypercouch\/\" }\r\n  }\r\n}<\/pre>\n<p>The <code>_links<\/code> object here feels at home among the native <code>_prefixed<\/code> CouchDB reserved keys. In this case, it contains the link relationships we saw earlier for <code>self<\/code> and <code>index<\/code>. I\u2019ve also added a collection link relationship from <a href=\"http:\/\/www.iana.org\/go\/rfc6573\">RFC6573<\/a>: \u201cThe Item and Collection Link Relations.\u201d Essentially, it points back to the database this document is contained within.<\/p>\n<p><code>GET \/{db}\/\\_all\\_docs<\/code><\/p>\n<pre class=\"brush:php\">{\r\n  \"total_rows\":2,\r\n  \"offset\":0,\r\n  \"rows\":[\r\n    {\r\n      \"id\": \"_design\/hal\",\r\n      \"key\": \"_design\/hal\",\r\n      \"value\": { \"rev\":\"1-0b1f6e8f2662fc5e7efcd9f930acec60\" }\r\n    },\r\n    {\r\n      \"id\": \"db74fd2411e1a0da283b3f0fc8000074\",\r\n      \"key\": \"db74fd2411e1a0da283b3f0fc8000074\",\r\n      \"value\": { \"rev\":\"1-1d7fcf86f6f6ec8d0e63f6de7af5ce81\" }\r\n   }\r\n]}<\/pre>\n<p>If CouchDB served its own JSON-based media type for this endpoint, it could have been defined to state that <code>id<\/code> here was a relative URL. However, since that didn\u2019t happen, we\u2019ll upgrade this one to HAL also. The changes to this one though are more significant and change the shape of the original JSON:<\/p>\n<pre class=\"brush:php\">{\r\n  \"total_rows\":2,\r\n  \"offset\":0,\r\n  \"_embedded\":{\r\n    \"item\": [\r\n    {\r\n      \"id\": \"_design\/hal\",\r\n      \"key\": \"_design\/hal\",\r\n      \"value\": { \"rev\":\"1-0b1f6e8f2662fc5e7efcd9f930acec60\" },\r\n      \"_links\": {\r\n        \"self\": { \"href\": \"\/hypercouch\/_design\/hal\" }\r\n      }\r\n    },\r\n    {\r\n      \"id\": \"db74fd2411e1a0da283b3f0fc8000074\",\r\n      \"key\": \"db74fd2411e1a0da283b3f0fc8000074\",\r\n      \"value\": { \"rev\":\"1-1d7fcf86f6f6ec8d0e63f6de7af5ce81\" },\r\n      \"_links\": {\r\n        \"self\": { \"href\": \"\/hypercouch\/db74fd2411e1a0da283b3f0fc8000074\" }\r\n      }\r\n    }\r\n  ],\r\n  \"_links\": {\r\n    \"self\": { \"href\": \"\/hypercouch\/_all_docs\" },\r\n    \"collection\": { \"href\": \"\/hypercouch\/\" }\r\n  }\r\n}<\/pre>\n<p>The <code>_embedded<\/code> object contains partial representations of the embedded resources. Each of these partial representations includes its own <code>_links<\/code> object which points to the <code>self<\/code> value which can be used to retrieve the entire representation \u2014 which of course contains a link back to the <code>index<\/code> and <code>collection<\/code>.<\/p>\n<p>Now, with these links in place, client code could start at any one of these endpoints and could follow the values of those link relationships \u2014 rather than hard coding URLs \u2014 to find its way around the database.<\/p>\n<h2>Write Semantics<\/h2>\n<p>One thing HAL leaves out of the equation are in-line hints about what methods can be used at which URL. Thankfully, HTTP has that skill.<\/p>\n<p>The HTTP <code>Allow<\/code> header is intended to provide a comma separated list of HTTP method names available on the requested resource. HTTP also comes with a handy <code>HEAD<\/code> method that allows you to only get the meta information about the resource \u2014 without the overhead of <code>GET<\/code>ing the entire representation.<\/p>\n<p>Alternatively, it\u2019s possible to simply attempt a <code>PUT<\/code> (for overwrite\/update) or <code>POST<\/code> (for append) operation and see how it goes. If the server\u2019s doing its job, it should respond with a <code>404 Method Not Allowed<\/code> error. If it\u2019s really doing its job well, then that response will have the <code>Allow<\/code> header.<\/p>\n<p>However, there are efforts, such as the in-progress <a href=\"http:\/\/rwcbook.github.io\/hal-forms\/\">HAL Forms specification<\/a>, that allow developers to encode HTML-style form information directly in the HAL response.<\/p>\n<h2>HAL Browsing<\/h2>\n<p>The HAL community has its own (minimal) browser for finding your way around these HAL responses know as (obviously enough) <a href=\"http:\/\/haltalk.herokuapp.com\/explorer\/browser.html\">the HAL Browser<\/a>. They have an example API which is loaded by default, but it also works on <code>localhost<\/code> URLs or your very own <code>hypercouch.dev<\/code> instance.<\/p>\n<h2>APIs + Links<\/h2>\n<p>In the end, your next API may be \u201cjust JSON\u201d over HTTP. However, your API will change, and when it does, how will you address those changes? The web, thanks in part to links and media types, has survived a couple decades of incremental change. Perhaps it\u2019s time our APIs were this resilient.<\/p>\n<div class=\"attribution\">\n<table>\n<tbody>\n<tr>\n<td><span class=\"reference\">Reference: <\/span><\/td>\n<td><a href=\"http:\/\/blog.codeship.com\/hypermedia-apis-apache-couchdb\/\">Hypermedia APIs with Apache CouchDB<\/a> from our <a href=\"http:\/\/www.webcodegeeks.com\/join-us\/wcg\/\">WCG partner<\/a> Florian Motlik at the <a href=\"http:\/\/blog.codeship.com\/\">Codeship Blog<\/a> blog.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>RESTful web services are a thing I love to discuss, build, and use. However, most of them stop short at sending JSON (or XML) back and forth over the wire. I read the documentation. I write some code with URLs in it and tie my JavaScript, Python, or PHP right into the vendor\u2019s API as &hellip;<\/p>\n","protected":false},"author":147,"featured_media":927,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8],"tags":[359],"class_list":["post-12069","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-web-development","tag-apache-couchdb"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.5 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Hypermedia APIs with Apache CouchDB - Web Code Geeks - 2026<\/title>\n<meta name=\"description\" content=\"RESTful web services are a thing I love to discuss, build, and use. However, most of them stop short at sending JSON (or XML) back and forth over the\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.webcodegeeks.com\/web-development\/hypermedia-apis-apache-couchdb\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Hypermedia APIs with Apache CouchDB - Web Code Geeks - 2026\" \/>\n<meta property=\"og:description\" content=\"RESTful web services are a thing I love to discuss, build, and use. However, most of them stop short at sending JSON (or XML) back and forth over the\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.webcodegeeks.com\/web-development\/hypermedia-apis-apache-couchdb\/\" \/>\n<meta property=\"og:site_name\" content=\"Web Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/webcodegeeks\" \/>\n<meta property=\"article:published_time\" content=\"2016-04-20T09:11:02+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/web-dev-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Benjamin Young\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@webcodegeeks\" \/>\n<meta name=\"twitter:site\" content=\"@webcodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Benjamin Young\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"8 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.webcodegeeks.com\/web-development\/hypermedia-apis-apache-couchdb\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/web-development\/hypermedia-apis-apache-couchdb\/\"},\"author\":{\"name\":\"Benjamin Young\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/caa7920cfde365335817761979a72407\"},\"headline\":\"Hypermedia APIs with Apache CouchDB\",\"datePublished\":\"2016-04-20T09:11:02+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/web-development\/hypermedia-apis-apache-couchdb\/\"},\"wordCount\":1289,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/web-development\/hypermedia-apis-apache-couchdb\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/web-dev-logo.jpg\",\"keywords\":[\"Apache CouchDB\"],\"articleSection\":[\"Web Dev\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.webcodegeeks.com\/web-development\/hypermedia-apis-apache-couchdb\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.webcodegeeks.com\/web-development\/hypermedia-apis-apache-couchdb\/\",\"url\":\"https:\/\/www.webcodegeeks.com\/web-development\/hypermedia-apis-apache-couchdb\/\",\"name\":\"Hypermedia APIs with Apache CouchDB - Web Code Geeks - 2026\",\"isPartOf\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/web-development\/hypermedia-apis-apache-couchdb\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/web-development\/hypermedia-apis-apache-couchdb\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/web-dev-logo.jpg\",\"datePublished\":\"2016-04-20T09:11:02+00:00\",\"description\":\"RESTful web services are a thing I love to discuss, build, and use. However, most of them stop short at sending JSON (or XML) back and forth over the\",\"breadcrumb\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/web-development\/hypermedia-apis-apache-couchdb\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.webcodegeeks.com\/web-development\/hypermedia-apis-apache-couchdb\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.webcodegeeks.com\/web-development\/hypermedia-apis-apache-couchdb\/#primaryimage\",\"url\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/web-dev-logo.jpg\",\"contentUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/web-dev-logo.jpg\",\"width\":150,\"height\":150},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.webcodegeeks.com\/web-development\/hypermedia-apis-apache-couchdb\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.webcodegeeks.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Web Dev\",\"item\":\"https:\/\/www.webcodegeeks.com\/category\/web-development\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Hypermedia APIs with Apache CouchDB\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#website\",\"url\":\"https:\/\/www.webcodegeeks.com\/\",\"name\":\"Web Code Geeks\",\"description\":\"Web Developers Resource Center\",\"publisher\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.webcodegeeks.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\/\/www.webcodegeeks.com\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png\",\"contentUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/webcodegeeks\",\"https:\/\/x.com\/webcodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/caa7920cfde365335817761979a72407\",\"name\":\"Benjamin Young\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/793ddd7d9809b369c04dbc92ea77a896112cc0a0e9a25417a43c17f4afb06f39?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/793ddd7d9809b369c04dbc92ea77a896112cc0a0e9a25417a43c17f4afb06f39?s=96&d=mm&r=g\",\"caption\":\"Benjamin Young\"},\"description\":\"Benjamin Young is a User Experience Engineer and Information Architect. He also organizes @RESTFest &amp; @OpenUpstate.\",\"url\":\"https:\/\/www.webcodegeeks.com\/author\/benjamin-young\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Hypermedia APIs with Apache CouchDB - Web Code Geeks - 2026","description":"RESTful web services are a thing I love to discuss, build, and use. However, most of them stop short at sending JSON (or XML) back and forth over the","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:\/\/www.webcodegeeks.com\/web-development\/hypermedia-apis-apache-couchdb\/","og_locale":"en_US","og_type":"article","og_title":"Hypermedia APIs with Apache CouchDB - Web Code Geeks - 2026","og_description":"RESTful web services are a thing I love to discuss, build, and use. However, most of them stop short at sending JSON (or XML) back and forth over the","og_url":"https:\/\/www.webcodegeeks.com\/web-development\/hypermedia-apis-apache-couchdb\/","og_site_name":"Web Code Geeks","article_publisher":"https:\/\/www.facebook.com\/webcodegeeks","article_published_time":"2016-04-20T09:11:02+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/web-dev-logo.jpg","type":"image\/jpeg"}],"author":"Benjamin Young","twitter_card":"summary_large_image","twitter_creator":"@webcodegeeks","twitter_site":"@webcodegeeks","twitter_misc":{"Written by":"Benjamin Young","Est. reading time":"8 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.webcodegeeks.com\/web-development\/hypermedia-apis-apache-couchdb\/#article","isPartOf":{"@id":"https:\/\/www.webcodegeeks.com\/web-development\/hypermedia-apis-apache-couchdb\/"},"author":{"name":"Benjamin Young","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/caa7920cfde365335817761979a72407"},"headline":"Hypermedia APIs with Apache CouchDB","datePublished":"2016-04-20T09:11:02+00:00","mainEntityOfPage":{"@id":"https:\/\/www.webcodegeeks.com\/web-development\/hypermedia-apis-apache-couchdb\/"},"wordCount":1289,"commentCount":0,"publisher":{"@id":"https:\/\/www.webcodegeeks.com\/#organization"},"image":{"@id":"https:\/\/www.webcodegeeks.com\/web-development\/hypermedia-apis-apache-couchdb\/#primaryimage"},"thumbnailUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/web-dev-logo.jpg","keywords":["Apache CouchDB"],"articleSection":["Web Dev"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.webcodegeeks.com\/web-development\/hypermedia-apis-apache-couchdb\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.webcodegeeks.com\/web-development\/hypermedia-apis-apache-couchdb\/","url":"https:\/\/www.webcodegeeks.com\/web-development\/hypermedia-apis-apache-couchdb\/","name":"Hypermedia APIs with Apache CouchDB - Web Code Geeks - 2026","isPartOf":{"@id":"https:\/\/www.webcodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.webcodegeeks.com\/web-development\/hypermedia-apis-apache-couchdb\/#primaryimage"},"image":{"@id":"https:\/\/www.webcodegeeks.com\/web-development\/hypermedia-apis-apache-couchdb\/#primaryimage"},"thumbnailUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/web-dev-logo.jpg","datePublished":"2016-04-20T09:11:02+00:00","description":"RESTful web services are a thing I love to discuss, build, and use. However, most of them stop short at sending JSON (or XML) back and forth over the","breadcrumb":{"@id":"https:\/\/www.webcodegeeks.com\/web-development\/hypermedia-apis-apache-couchdb\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.webcodegeeks.com\/web-development\/hypermedia-apis-apache-couchdb\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.webcodegeeks.com\/web-development\/hypermedia-apis-apache-couchdb\/#primaryimage","url":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/web-dev-logo.jpg","contentUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/web-dev-logo.jpg","width":150,"height":150},{"@type":"BreadcrumbList","@id":"https:\/\/www.webcodegeeks.com\/web-development\/hypermedia-apis-apache-couchdb\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.webcodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"Web Dev","item":"https:\/\/www.webcodegeeks.com\/category\/web-development\/"},{"@type":"ListItem","position":3,"name":"Hypermedia APIs with Apache CouchDB"}]},{"@type":"WebSite","@id":"https:\/\/www.webcodegeeks.com\/#website","url":"https:\/\/www.webcodegeeks.com\/","name":"Web Code Geeks","description":"Web Developers Resource Center","publisher":{"@id":"https:\/\/www.webcodegeeks.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.webcodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.webcodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/www.webcodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/webcodegeeks","https:\/\/x.com\/webcodegeeks"]},{"@type":"Person","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/caa7920cfde365335817761979a72407","name":"Benjamin Young","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/793ddd7d9809b369c04dbc92ea77a896112cc0a0e9a25417a43c17f4afb06f39?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/793ddd7d9809b369c04dbc92ea77a896112cc0a0e9a25417a43c17f4afb06f39?s=96&d=mm&r=g","caption":"Benjamin Young"},"description":"Benjamin Young is a User Experience Engineer and Information Architect. He also organizes @RESTFest &amp; @OpenUpstate.","url":"https:\/\/www.webcodegeeks.com\/author\/benjamin-young\/"}]}},"_links":{"self":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/posts\/12069","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/users\/147"}],"replies":[{"embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/comments?post=12069"}],"version-history":[{"count":0,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/posts\/12069\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/media\/927"}],"wp:attachment":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/media?parent=12069"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/categories?post=12069"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/tags?post=12069"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}