{"id":930,"date":"2014-02-13T21:19:35","date_gmt":"2014-02-13T15:49:35","guid":{"rendered":"http:\/\/www.allerin.com\/blog\/?p=930"},"modified":"2014-02-13T22:11:25","modified_gmt":"2014-02-13T16:41:25","slug":"caching-in-ruby-with-rails","status":"publish","type":"post","link":"https:\/\/www.allerin.com\/blog\/caching-in-ruby-with-rails\/","title":{"rendered":"Caching in Ruby with Rails"},"content":{"rendered":"<p>There are three types of caching supported by Rails &#8216;Page Caching&#8217;, &#8216;Action Caching&#8217; and &#8216;Fragment Caching&#8217;.<\/p>\n<p><strong>Page Caching:<\/strong><\/p>\n<p>Page caching allows the request for a generated page to be fulfilled by the webserver (i.e. Apache or Nginx), without ever having to go through the Rails stack at all.<br \/>\nThis is very nice technique but cannot be used in all the situations like pages which needs authentication, also the overhead of implementing the Cache Expiration mechanism.<\/p>\n<p><strong>Action Caching:<\/strong><br \/>\nAction Caching is same as Page Caching the only difference in this is the request will hit the Rails stack, and will allow the authentication and other restrictions to be enforced before serving the cache.<\/p>\n<p>However, &#8216;Page&#8217; and &#8216;Action&#8217; cachings have been removed from Rails4 and separated into gems(i.e. <a href=\"https:\/\/github.com\/rails\/actionpack-page_caching\" target=\"_blank\">actionpack-page_caching<\/a> gem and <a href=\"https:\/\/github.com\/rails\/actionpack-action_caching\" target=\"_blank\">actionpack-action_caching<\/a> gem).<\/p>\n<p><strong>Fragment Caching:<\/strong><\/p>\n<p>Fragment caching refers to caching a fragment(part) of a page.<br \/>\nRails &#8216;ActionView&#8217; templates provide ease of coding, implementing and maintenance to developer using Templates, Partials and Layouts. But the generation of actual HTML is very complex and slow process.<\/p>\n<p>Fragment Caching allows a fragment of view logic to be wrapped in a cache block and served out of the cache store when the next request comes in.<\/p>\n<p>Example:<\/p>\n<pre>&lt;% cache do %&gt;\r\n  &lt;% @projects.each do |project| %&gt;\r\n    &lt;h3&gt;&lt;%= link_to project.name, project %&gt;&lt;\/h3&gt;\r\n    &lt;%= render partial: 'tasks\/task', collection: project.tasks %&gt;\r\n  &lt;% end %&gt;\r\n&lt;% end %&gt;<\/pre>\n<p>The cache block in above example will get binded to the action that will call it. To have multiple caches per action cache method must be passed action_suffix as below.<\/p>\n<pre>&lt;% cache :action =&gt; 'index', :action_suffix =&gt; 'all_projects' do %&gt;\r\n  &lt;% @projects.each do |project| %&gt;\r\n    &lt;h3&gt;&lt;%= link_to project.name, project %&gt;&lt;\/h3&gt;\r\n    &lt;%= render partial: 'tasks\/task', collection: project.tasks %&gt;\r\n  &lt;% end %&gt;\r\n&lt;% end %&gt;<\/pre>\n<p>It is possible to define cache without binding it to some action, instead using a global key.<br \/>\nExample:<\/p>\n<pre>&lt;% cache 'all_projects_with_tasks' do %&gt;\r\n  &lt;% @projects.each do |project| %&gt;\r\n    &lt;h3&gt;&lt;%= link_to project.name, project %&gt;&lt;\/h3&gt;\r\n    &lt;%= render partial: 'tasks\/task', collection: project.tasks %&gt;\r\n  &lt;% end %&gt;\r\n&lt;% end %&gt;<\/pre>\n<p>In all of the previous example, the cache will not get invalidated after a change in any object or in template itself.<br \/>\nCache can be expired as below<br \/>\nexpire_fragment(controller: &#8216;projects&#8217;, action: &#8216;index&#8217;, action_suffix: &#8216;all_projects&#8217;)<br \/>\nexpire_fragment(&#8216;all_projects_with_tasks&#8217;) # for global keyed cache<\/p>\n<p><strong>ActiveRecord object as Caching key<\/strong><\/p>\n<p>Example:<\/p>\n<pre>&lt;% @projects.each do |project| %&gt;\r\n  &lt;% cache project do %&gt;\r\n    &lt;h3&gt;&lt;%= link_to project.name, project %&gt;&lt;\/h3&gt;\r\n    &lt;%= render partial: 'tasks\/task', collection: project.tasks %&gt;\r\n  &lt;% end %&gt;\r\n&lt;% end %&gt;<\/pre>\n<p>In the above example, the raltive cache for the project will get expired automatically after update into it. Because the cache key generated based on object timestamp.<br \/>\nBut in the above example the problem is if there will be any changes in template(in html structure) the cache wont get invalidated automatically.<br \/>\nThe workaround for it is, add a version number to cache key, and change the version number every time the template is being changed.<br \/>\nLike &lt;% cache [&#8216;v1&#8217;, project] do %&gt;<\/p>\n<p><strong>Nested Caching:<\/strong><\/p>\n<p>Example:<\/p>\n<pre>&lt;% @projects.each do |project| %&gt;\r\n  &lt;% cache ['v1', project] do %&gt;\r\n    &lt;h3&gt;&lt;%= link_to project.name, project %&gt;&lt;\/h3&gt;\r\n    &lt;%= render partial: 'tasks\/task', collection: project.tasks %&gt;\r\n  &lt;% end %&gt;\r\n&lt;% end %&gt;<\/pre>\n<p>tasks\/task partial:<\/p>\n<pre>&lt;ul&gt;\r\n  &lt;% cache ['v1', task ] do %&gt;\r\n    &lt;li&gt;&lt;%= task.description %&gt;&lt;\/li&gt;\r\n    &lt;li&gt;&lt;%= task.due_date %&gt;&lt;\/li&gt;\r\n  &lt;% end %&gt;\r\n&lt;\/ul&gt;<\/pre>\n<p>The above is an example of nested caching, But there are few problems with this implementation:<br \/>\n1. Every time the changes done in inner template\/partial(here it is tasks\/_task.html.erb), the cache version number must get updated for its parent cache fragment member.<br \/>\n2. When the project object is changed the cache will get expired automatically because of change in the object timestamp. But when any task is updated the project cache wont get expired, to overcome with this we can update project object whenever any task is being changed using \u201c:touch =&gt; true\u201d<\/p>\n<p>In Task Model:<br \/>\nbelongs_to :project, :touch =&gt; true # this will update the associated project object on updation on a task. And thus will expire the project cache.<br \/>\nIt&#8217;s called &#8220;Russian Doll Caching&#8221; because it nests multiple fragments. The advantage is that if a single product is updated, all the other inner fragments can be reused when regenerating the outer fragment.<\/p>\n<p><strong>Russian Doll Caching with CacheDigest<\/strong><br \/>\nForget about all the complex methods of fragment caching like versioning fragments or expiring it manually, because Rails4 has cache_digest to deal with the auto expiration of cache.<br \/>\nWith cache digests, unique cache keys are formed using a md5 stamp based on the timestamp of the object being cached<br \/>\nThe advantage of this is that when objects are updated, and outer fragments are automatically invalidated, Other nested fragments can be re-used which is called as RussianDoll.<br \/>\nOnly the key requirement to this is that children objects should update the timestamps of their parent object by using ActiveRecord touch option. This will invalidate the old cache and will generate and serve new cache.<\/p>\n<p>NOTE: cache_digest is also extracted into a separate gem and can be used with Rails3 applications. <a href=\"https:\/\/github.com\/rails\/cache_digests\" target=\"_blank\">https:\/\/github.com\/rails\/cache_digests<\/a><\/p>\n<p><strong>Performance Impact:<\/strong><br \/>\nBe careful while using cache, because it may decrease your application performance if not used intelligently.<\/p>\n<p>Net cache impact = (benefit from hit x hit rate) \u2013 (cost of miss x miss rate)<br \/>\nCost of a cache miss penalty is always the number of times of cache-hit time, So more frequent cache miss may reduce the application performance significantly instead of improving it.<\/p>\n<p><strong>Points to Remember:<\/strong><br \/>\n1. Cache fragment with a low hit rate that is also quick to render on a miss might be better off not being cached at all. The costs of all of the misses outweigh the benefits of a hit.<br \/>\n2. A template that is extremely slow to render might still benefit on net even if only 10% of cache requests are successful.<\/p>\n<p>For reference I recommend\u00a0 <a href=\"http:\/\/signalvnoise.com\/posts\/3690-the-performance-impact-of-russian-doll-caching\" target=\"_blank\">The performance impact of &#8216;Russian doll&#8217;<\/a> caching post by Noah Lorang &#8211; data analyst for Basecamp<\/p>\n<p>&nbsp;<\/p>\n<p>Hope this post could help fellow RoR enthusiast, Happy coding \ud83d\ude42<\/p>\n","protected":false},"excerpt":{"rendered":"<p>There are three types of caching supported by Rails &#8216;Page Caching&#8217;, &#8216;Action Caching&#8217; and &#8216;Fragment Caching&#8217;. Page Caching: Page caching allows the request for a generated page to be fulfilled&#8230;<\/p>\n","protected":false},"author":13,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_links_to":"","_links_to_target":""},"categories":[3],"tags":[99,101,20,100],"class_list":["post-930","post","type-post","status-publish","format-standard","hentry","category-technology","tag-caching","tag-caching-in-ruby-on-rails","tag-ruby-on-rails","tag-russian-dolls"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.5 (Yoast SEO v27.6) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Caching in Ruby with Rails - Artificial Intelligence, ROBOTICS, AUTOMATION<\/title>\n<meta name=\"description\" content=\"There are three types of caching supported by Rails &#039;Page Caching&#039;, &#039;Action Caching&#039; and &#039;Fragment Caching&#039;. Page Caching: Page caching allows the request\" \/>\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.allerin.com\/blog\/caching-in-ruby-with-rails\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Caching in Ruby with Rails\" \/>\n<meta property=\"og:description\" content=\"There are three types of caching supported by Rails &#039;Page Caching&#039;, &#039;Action Caching&#039; and &#039;Fragment Caching&#039;. Page Caching: Page caching allows the request\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.allerin.com\/blog\/caching-in-ruby-with-rails\/\" \/>\n<meta property=\"og:site_name\" content=\"Artificial Intelligence, ROBOTICS, AUTOMATION\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/allerintech\" \/>\n<meta property=\"article:published_time\" content=\"2014-02-13T15:49:35+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2014-02-13T16:41:25+00:00\" \/>\n<meta name=\"author\" content=\"Nitesh Varma\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Nitesh Varma\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"5 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.allerin.com\\\/blog\\\/caching-in-ruby-with-rails\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.allerin.com\\\/blog\\\/caching-in-ruby-with-rails\\\/\"},\"author\":{\"name\":\"Nitesh Varma\",\"@id\":\"https:\\\/\\\/www.allerin.com\\\/blog\\\/#\\\/schema\\\/person\\\/62051995e859f22af8935f2c15a7f00d\"},\"headline\":\"Caching in Ruby with Rails\",\"datePublished\":\"2014-02-13T15:49:35+00:00\",\"dateModified\":\"2014-02-13T16:41:25+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.allerin.com\\\/blog\\\/caching-in-ruby-with-rails\\\/\"},\"wordCount\":858,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/www.allerin.com\\\/blog\\\/#organization\"},\"keywords\":[\"caching\",\"caching in ruby on rails\",\"Ruby on Rails\",\"russian dolls\"],\"articleSection\":[\"Technology\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.allerin.com\\\/blog\\\/caching-in-ruby-with-rails\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.allerin.com\\\/blog\\\/caching-in-ruby-with-rails\\\/\",\"url\":\"https:\\\/\\\/www.allerin.com\\\/blog\\\/caching-in-ruby-with-rails\\\/\",\"name\":\"Caching in Ruby with Rails - Artificial Intelligence, ROBOTICS, AUTOMATION\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.allerin.com\\\/blog\\\/#website\"},\"datePublished\":\"2014-02-13T15:49:35+00:00\",\"dateModified\":\"2014-02-13T16:41:25+00:00\",\"description\":\"There are three types of caching supported by Rails 'Page Caching', 'Action Caching' and 'Fragment Caching'. Page Caching: Page caching allows the request\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.allerin.com\\\/blog\\\/caching-in-ruby-with-rails\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.allerin.com\\\/blog\\\/caching-in-ruby-with-rails\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.allerin.com\\\/blog\\\/caching-in-ruby-with-rails\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.allerin.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Caching in Ruby with Rails\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.allerin.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.allerin.com\\\/blog\\\/\",\"name\":\"Artificial Intelligence, ROBOTICS, AUTOMATION\",\"description\":\"Empowering Futures: Innovating with AI and Machine Learning\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.allerin.com\\\/blog\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.allerin.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.allerin.com\\\/blog\\\/#organization\",\"name\":\"Allerin\",\"url\":\"https:\\\/\\\/www.allerin.com\\\/blog\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.allerin.com\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.allerin.com\\\/blog\\\/wp-content\\\/uploads\\\/2016\\\/06\\\/logo-fire.png\",\"contentUrl\":\"https:\\\/\\\/www.allerin.com\\\/blog\\\/wp-content\\\/uploads\\\/2016\\\/06\\\/logo-fire.png\",\"width\":1000,\"height\":1000,\"caption\":\"Allerin\"},\"image\":{\"@id\":\"https:\\\/\\\/www.allerin.com\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/allerintech\",\"https:\\\/\\\/www.linkedin.com\\\/company\\\/allerintech\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.allerin.com\\\/blog\\\/#\\\/schema\\\/person\\\/62051995e859f22af8935f2c15a7f00d\",\"name\":\"Nitesh Varma\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/b21e15576ea716b8c732b52f63ca14cccbe5d0d086a907d9017b5146f5c7237a?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/b21e15576ea716b8c732b52f63ca14cccbe5d0d086a907d9017b5146f5c7237a?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/b21e15576ea716b8c732b52f63ca14cccbe5d0d086a907d9017b5146f5c7237a?s=96&d=mm&r=g\",\"caption\":\"Nitesh Varma\"},\"sameAs\":[\"http:\\\/\\\/www.allerin.com\"],\"url\":\"https:\\\/\\\/www.allerin.com\\\/blog\\\/author\\\/niteshv\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Caching in Ruby with Rails - Artificial Intelligence, ROBOTICS, AUTOMATION","description":"There are three types of caching supported by Rails 'Page Caching', 'Action Caching' and 'Fragment Caching'. Page Caching: Page caching allows the request","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.allerin.com\/blog\/caching-in-ruby-with-rails\/","og_locale":"en_US","og_type":"article","og_title":"Caching in Ruby with Rails","og_description":"There are three types of caching supported by Rails 'Page Caching', 'Action Caching' and 'Fragment Caching'. Page Caching: Page caching allows the request","og_url":"https:\/\/www.allerin.com\/blog\/caching-in-ruby-with-rails\/","og_site_name":"Artificial Intelligence, ROBOTICS, AUTOMATION","article_publisher":"https:\/\/www.facebook.com\/allerintech","article_published_time":"2014-02-13T15:49:35+00:00","article_modified_time":"2014-02-13T16:41:25+00:00","author":"Nitesh Varma","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Nitesh Varma","Est. reading time":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.allerin.com\/blog\/caching-in-ruby-with-rails\/#article","isPartOf":{"@id":"https:\/\/www.allerin.com\/blog\/caching-in-ruby-with-rails\/"},"author":{"name":"Nitesh Varma","@id":"https:\/\/www.allerin.com\/blog\/#\/schema\/person\/62051995e859f22af8935f2c15a7f00d"},"headline":"Caching in Ruby with Rails","datePublished":"2014-02-13T15:49:35+00:00","dateModified":"2014-02-13T16:41:25+00:00","mainEntityOfPage":{"@id":"https:\/\/www.allerin.com\/blog\/caching-in-ruby-with-rails\/"},"wordCount":858,"commentCount":0,"publisher":{"@id":"https:\/\/www.allerin.com\/blog\/#organization"},"keywords":["caching","caching in ruby on rails","Ruby on Rails","russian dolls"],"articleSection":["Technology"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.allerin.com\/blog\/caching-in-ruby-with-rails\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.allerin.com\/blog\/caching-in-ruby-with-rails\/","url":"https:\/\/www.allerin.com\/blog\/caching-in-ruby-with-rails\/","name":"Caching in Ruby with Rails - Artificial Intelligence, ROBOTICS, AUTOMATION","isPartOf":{"@id":"https:\/\/www.allerin.com\/blog\/#website"},"datePublished":"2014-02-13T15:49:35+00:00","dateModified":"2014-02-13T16:41:25+00:00","description":"There are three types of caching supported by Rails 'Page Caching', 'Action Caching' and 'Fragment Caching'. Page Caching: Page caching allows the request","breadcrumb":{"@id":"https:\/\/www.allerin.com\/blog\/caching-in-ruby-with-rails\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.allerin.com\/blog\/caching-in-ruby-with-rails\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.allerin.com\/blog\/caching-in-ruby-with-rails\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.allerin.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Caching in Ruby with Rails"}]},{"@type":"WebSite","@id":"https:\/\/www.allerin.com\/blog\/#website","url":"https:\/\/www.allerin.com\/blog\/","name":"Artificial Intelligence, ROBOTICS, AUTOMATION","description":"Empowering Futures: Innovating with AI and Machine Learning","publisher":{"@id":"https:\/\/www.allerin.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.allerin.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.allerin.com\/blog\/#organization","name":"Allerin","url":"https:\/\/www.allerin.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.allerin.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.allerin.com\/blog\/wp-content\/uploads\/2016\/06\/logo-fire.png","contentUrl":"https:\/\/www.allerin.com\/blog\/wp-content\/uploads\/2016\/06\/logo-fire.png","width":1000,"height":1000,"caption":"Allerin"},"image":{"@id":"https:\/\/www.allerin.com\/blog\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/allerintech","https:\/\/www.linkedin.com\/company\/allerintech"]},{"@type":"Person","@id":"https:\/\/www.allerin.com\/blog\/#\/schema\/person\/62051995e859f22af8935f2c15a7f00d","name":"Nitesh Varma","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/b21e15576ea716b8c732b52f63ca14cccbe5d0d086a907d9017b5146f5c7237a?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/b21e15576ea716b8c732b52f63ca14cccbe5d0d086a907d9017b5146f5c7237a?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/b21e15576ea716b8c732b52f63ca14cccbe5d0d086a907d9017b5146f5c7237a?s=96&d=mm&r=g","caption":"Nitesh Varma"},"sameAs":["http:\/\/www.allerin.com"],"url":"https:\/\/www.allerin.com\/blog\/author\/niteshv\/"}]}},"_links":{"self":[{"href":"https:\/\/www.allerin.com\/blog\/wp-json\/wp\/v2\/posts\/930","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.allerin.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.allerin.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.allerin.com\/blog\/wp-json\/wp\/v2\/users\/13"}],"replies":[{"embeddable":true,"href":"https:\/\/www.allerin.com\/blog\/wp-json\/wp\/v2\/comments?post=930"}],"version-history":[{"count":4,"href":"https:\/\/www.allerin.com\/blog\/wp-json\/wp\/v2\/posts\/930\/revisions"}],"predecessor-version":[{"id":934,"href":"https:\/\/www.allerin.com\/blog\/wp-json\/wp\/v2\/posts\/930\/revisions\/934"}],"wp:attachment":[{"href":"https:\/\/www.allerin.com\/blog\/wp-json\/wp\/v2\/media?parent=930"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.allerin.com\/blog\/wp-json\/wp\/v2\/categories?post=930"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.allerin.com\/blog\/wp-json\/wp\/v2\/tags?post=930"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}