{"id":1673,"date":"2014-12-16T19:38:30","date_gmt":"2014-12-16T19:38:29","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=1673"},"modified":"2017-04-19T14:08:44","modified_gmt":"2017-04-19T21:08:44","slug":"libmembase-c-interface-membase","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/libmembase-c-interface-membase\/","title":{"rendered":"libmembase \u2013 a C interface to Membase"},"content":{"rendered":"<p>Membase is &#8220;on the wire&#8221; compatible with any memcached server if you connect to the <a href=\"https:\/\/www.iana.org\/assignments\/port-numbers\"><u><span style=\"color: #de7008;\">standard memcached port<\/span><\/u><\/a> (registered by myself back in 2009), so that you should should be able to access membase with any &#8220;memcapable&#8221; client. Backing this port is our membase proxy named moxi, and behind the scene it will do SASL authentication and proxy your requests to the correct membase server containing the item you want. One of the things that differs Membase from Memcached is that we store each item in a given <a href=\"https:\/\/wiki.membase.org\/display\/membase\/vBuckets\"><u><span style=\"color: #de7008;\">vbucket<\/span><\/u><\/a> that is mapped to a server. When you grow or shrink the cluster, membase will move the vbuckets to new servers.<\/p>\n<p>There is no such thing as a free lunch, so accessing membase through moxi &#8220;costs&#8221; more than talking directly to the individual nodes yourself. We like to refer to such clients as &#8220;smart clients.&#8221; As a developer on Memcached I need to test various stuff, so I went ahead and hacked together a quick prototype of such a library to ease my testing. Initially I wanted to extend libmemcached with this functionality, but that seemed to be a big (and risky) change I didn&#8217;t have the guts to do at the time.<\/p>\n<p>The current state of the library is far from production quality, and with a minimal list of supported features. So why announce it now? Well I don&#8217;t think I&#8217;ll find the time to implement everything myself, so I&#8217;m hoping that people will join me in adding features to the library when they need something that isn&#8217;t there&#8230;<\/p>\n<p>I&#8217;ve designed the library to be 100% callback based and integrated with libevent, making it easy for you to plug it into your application.<\/p>\n<p>So let&#8217;s say you want to create a TAP stream and listen to all of the modifications that happens in your cluster. All you need to do would be:<\/p>\n<div class=\"geshifilter\">\n<div class=\"text geshifilter-text\" style=\"font-family: monospace;\">\n<p>struct event_base *evbase = event_init();<\/p>\n<p>libmembase_t instance = libmembase_create(host, username, passwd, bucket, evbase);<br \/>\nlibmembase_connect(instance);<\/p>\n<p>libmembase_tap_filter_t filter;<br \/>\nlibmembase_callback_t callbacks = {<br \/>\n.tap_mutation = tap_mutation<br \/>\n};<br \/>\nlibmembase_set_callbacks(instance, &amp;callbacks);<br \/>\nlibmembase_tap_cluster(instance, filter, true);<\/p>\n<\/div>\n<\/div>\n<p>Then you would implement the tap callback function as:<\/p>\n<div class=\"geshifilter\">\n<div class=\"text geshifilter-text\" style=\"font-family: monospace;\">static void tap_mutation(libmembase_t instance, const void *key, size_t nkey, const void<br \/>\n*data, size_t nbytes, uint32_t flags, uint32_t exp, const void *es, size_t nes)<br \/>\n{<br \/>\n\/\/ Do whatever you want with the object<br \/>\n}<\/div>\n<\/div>\n<p>And thats all you need to do to tap your entire cluster :-) Let&#8217;s extend the example to tap <u>multiple<\/u> buckets from the same code.<\/p>\n<div class=\"geshifilter\">\n<div class=\"text geshifilter-text\" style=\"font-family: monospace;\">\n<p>struct event_base *evbase = event_init();<\/p>\n<p>libmembase_t instance1 = libmembase_create(host, username, passwd, bucket1, evbase);<br \/>\nlibmembase_t instance2 = libmembase_create(host, username, passwd, bucket2, evbase);<br \/>\nlibmembase_connect(instance1);<br \/>\nlibmembase_connect(instance2);<\/p>\n<p>libmembase_tap_filter_t filter;<br \/>\nlibmembase_callback_t callbacks = {<br \/>\n.tap_mutation = tap_mutation<br \/>\n};<br \/>\nlibmembase_set_callbacks(instance1, &amp;callbacks);<br \/>\nlibmembase_set_callbacks(instance2, &amp;callbacks);<br \/>\nlibmembase_tap_cluster(instance1, filter, false);<br \/>\nlibmembase_tap_cluster(instance2, filter, false);<\/p>\n<p>event_base_loop(evbase, 0);<\/p>\n<\/div>\n<\/div>\n<p>The instance handle is passed to the callback function so you should be able to tell which bucket each mutation event belongs to.<\/p>\n<p>As I said all of the functions in the API is callback based, so if you want to retrieve an object you have to register a callback for <code><span style=\"color: #999999;\">get<\/span><\/code> before calling <code><span style=\"color: #999999;\">libmembase_mget<\/span><\/code>. Ex:<\/p>\n<div class=\"geshifilter\">\n<div class=\"text geshifilter-text\" style=\"font-family: monospace;\">libmembase_callback_t callbacks = {<br \/>\n.get = get_callback<br \/>\n};<br \/>\nlibmembase_set_callbacks(instance, &amp;callbacks);<br \/>\nlibmembase_mget(instance, num_keys, (const void * const *)keys, nkey);\/\/ If you don&#8217;t want to run your own event loop, you can call the following method<br \/>\n\/\/ that will run all spooled commands and wait for their replies before breaking out<br \/>\n\/\/ of the event loop<br \/>\nlibmembase_execute(instance);<\/p>\n<\/div>\n<\/div>\n<p>The signature for the get callback looks like:<\/p>\n<div class=\"geshifilter\">\n<div class=\"text geshifilter-text\" style=\"font-family: monospace;\">void get_callback(libmembase_t instance, libmembase_error_t error, const void *key,<br \/>\nsize_t nkey, const void *bytes, size_t nbytes, uint32_t flags, uint64_t cas)<br \/>\n{<br \/>\n\/\/ do whatever you want&#8230;<br \/>\n}<\/div>\n<\/div>\n<p>So what is missing from the library right now?<\/p>\n<p class=\"rteindent1\">\u2022 Proper error handling. Right now I&#8217;m using asserts and abort() to handle error\u00a0situations,\u00a0causing your application to crash&#8230; you don&#8217;t want that in production ;-)<br \/>\n\u2022 Timeouts.. Right now it will only time out on TCP timeouts..\/<br \/>\n\u2022 A lot of operations! I&#8217;m only supporting get\/add\/replace\/set&#8230;<br \/>\n\u2022 Fetch replicas..<br \/>\n\u2022 Gracefully handle change in the vbucket list<br \/>\n\u2022 +++<\/p>\n<p>Do you feel like hacking on some of them?<\/p>\n<p>For more on where to get and build libmemcached, click here.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Membase is &#8220;on the wire&#8221; compatible with any memcached server if you connect to the standard memcached port (registered by myself back in 2009), so that you should should be able to access membase with any &#8220;memcapable&#8221; client. Backing this [&hellip;]<\/p>\n","protected":false},"author":14,"featured_media":13873,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[1],"tags":[],"ppma_author":[8981],"class_list":["post-1673","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.8 (Yoast SEO v25.8) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>libmembase \u2013 a C interface to Membase - The Couchbase Blog<\/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:\/\/www.couchbase.com\/blog\/libmembase-c-interface-membase\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"libmembase \u2013 a C interface to Membase\" \/>\n<meta property=\"og:description\" content=\"Membase is &#8220;on the wire&#8221; compatible with any memcached server if you connect to the standard memcached port (registered by myself back in 2009), so that you should should be able to access membase with any &#8220;memcapable&#8221; client. Backing this [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/libmembase-c-interface-membase\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:published_time\" content=\"2014-12-16T19:38:29+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2017-04-19T21:08:44+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2022\/11\/couchbase-nosql-dbaas.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1800\" \/>\n\t<meta property=\"og:image:height\" content=\"630\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Trond Norbye, Senior Developer, Couchbase\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Trond Norbye, Senior Developer, Couchbase\" \/>\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\":\"Article\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/libmembase-c-interface-membase\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/libmembase-c-interface-membase\/\"},\"author\":{\"name\":\"Trond Norbye, Senior Developer, Couchbase\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/ef0f9ff42d878c2fc0ab3a685e96f36d\"},\"headline\":\"libmembase \u2013 a C interface to Membase\",\"datePublished\":\"2014-12-16T19:38:29+00:00\",\"dateModified\":\"2017-04-19T21:08:44+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/libmembase-c-interface-membase\/\"},\"wordCount\":757,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/libmembase-c-interface-membase\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/libmembase-c-interface-membase\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/libmembase-c-interface-membase\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/libmembase-c-interface-membase\/\",\"name\":\"libmembase \u2013 a C interface to Membase - The Couchbase Blog\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/libmembase-c-interface-membase\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/libmembase-c-interface-membase\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"datePublished\":\"2014-12-16T19:38:29+00:00\",\"dateModified\":\"2017-04-19T21:08:44+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/libmembase-c-interface-membase\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/libmembase-c-interface-membase\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/libmembase-c-interface-membase\/#primaryimage\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"width\":1800,\"height\":630},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/libmembase-c-interface-membase\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.couchbase.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"libmembase \u2013 a C interface to Membase\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"name\":\"The Couchbase Blog\",\"description\":\"Couchbase, the NoSQL Database\",\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\",\"name\":\"The Couchbase Blog\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"width\":218,\"height\":34,\"caption\":\"The Couchbase Blog\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/ef0f9ff42d878c2fc0ab3a685e96f36d\",\"name\":\"Trond Norbye, Senior Developer, Couchbase\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/03d13b4ab5eaa14c91cab7658f04df07\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/bf3c00ca228efa25f7bfc168f566d6389279b44d4bbba4683c260a8bf33da03d?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/bf3c00ca228efa25f7bfc168f566d6389279b44d4bbba4683c260a8bf33da03d?s=96&d=mm&r=g\",\"caption\":\"Trond Norbye, Senior Developer, Couchbase\"},\"description\":\"Trond Norbye is a Software Architect at Couchbase. Core contributor to Couchbase &amp; Memcached projects. Created the C\/C++ &amp; node.js Couchbase client libraries.\",\"url\":\"https:\/\/www.couchbase.com\/blog\/author\/trond-norbye\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"libmembase \u2013 a C interface to Membase - The Couchbase Blog","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.couchbase.com\/blog\/libmembase-c-interface-membase\/","og_locale":"en_US","og_type":"article","og_title":"libmembase \u2013 a C interface to Membase","og_description":"Membase is &#8220;on the wire&#8221; compatible with any memcached server if you connect to the standard memcached port (registered by myself back in 2009), so that you should should be able to access membase with any &#8220;memcapable&#8221; client. Backing this [&hellip;]","og_url":"https:\/\/www.couchbase.com\/blog\/libmembase-c-interface-membase\/","og_site_name":"The Couchbase Blog","article_published_time":"2014-12-16T19:38:29+00:00","article_modified_time":"2017-04-19T21:08:44+00:00","og_image":[{"width":1800,"height":630,"url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2022\/11\/couchbase-nosql-dbaas.png","type":"image\/png"}],"author":"Trond Norbye, Senior Developer, Couchbase","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Trond Norbye, Senior Developer, Couchbase","Est. reading time":"4 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/libmembase-c-interface-membase\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/libmembase-c-interface-membase\/"},"author":{"name":"Trond Norbye, Senior Developer, Couchbase","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/ef0f9ff42d878c2fc0ab3a685e96f36d"},"headline":"libmembase \u2013 a C interface to Membase","datePublished":"2014-12-16T19:38:29+00:00","dateModified":"2017-04-19T21:08:44+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/libmembase-c-interface-membase\/"},"wordCount":757,"commentCount":0,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/libmembase-c-interface-membase\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/libmembase-c-interface-membase\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/libmembase-c-interface-membase\/","url":"https:\/\/www.couchbase.com\/blog\/libmembase-c-interface-membase\/","name":"libmembase \u2013 a C interface to Membase - The Couchbase Blog","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/libmembase-c-interface-membase\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/libmembase-c-interface-membase\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","datePublished":"2014-12-16T19:38:29+00:00","dateModified":"2017-04-19T21:08:44+00:00","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/libmembase-c-interface-membase\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/libmembase-c-interface-membase\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/libmembase-c-interface-membase\/#primaryimage","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","width":1800,"height":630},{"@type":"BreadcrumbList","@id":"https:\/\/www.couchbase.com\/blog\/libmembase-c-interface-membase\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"libmembase \u2013 a C interface to Membase"}]},{"@type":"WebSite","@id":"https:\/\/www.couchbase.com\/blog\/#website","url":"https:\/\/www.couchbase.com\/blog\/","name":"The Couchbase Blog","description":"Couchbase, the NoSQL Database","publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.couchbase.com\/blog\/#organization","name":"The Couchbase Blog","url":"https:\/\/www.couchbase.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","width":218,"height":34,"caption":"The Couchbase Blog"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/ef0f9ff42d878c2fc0ab3a685e96f36d","name":"Trond Norbye, Senior Developer, Couchbase","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/03d13b4ab5eaa14c91cab7658f04df07","url":"https:\/\/secure.gravatar.com\/avatar\/bf3c00ca228efa25f7bfc168f566d6389279b44d4bbba4683c260a8bf33da03d?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/bf3c00ca228efa25f7bfc168f566d6389279b44d4bbba4683c260a8bf33da03d?s=96&d=mm&r=g","caption":"Trond Norbye, Senior Developer, Couchbase"},"description":"Trond Norbye is a Software Architect at Couchbase. Core contributor to Couchbase &amp; Memcached projects. Created the C\/C++ &amp; node.js Couchbase client libraries.","url":"https:\/\/www.couchbase.com\/blog\/author\/trond-norbye\/"}]}},"authors":[{"term_id":8981,"user_id":14,"is_guest":0,"slug":"trond-norbye","display_name":"Trond Norbye, Senior Developer, Couchbase","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/bf3c00ca228efa25f7bfc168f566d6389279b44d4bbba4683c260a8bf33da03d?s=96&d=mm&r=g","author_category":"","last_name":"Norbye","first_name":"Trond","job_title":"","user_url":"","description":"Trond Norbye is a Software Architect at Couchbase. Core contributor to Couchbase &amp; Memcached projects. Created the C\/C++ &amp; node.js Couchbase client libraries."}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts\/1673","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/users\/14"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/comments?post=1673"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts\/1673\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/media\/13873"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/media?parent=1673"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/categories?post=1673"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/tags?post=1673"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/ppma_author?post=1673"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}