{"id":1031,"date":"2014-07-21T12:53:01","date_gmt":"2014-07-21T07:23:01","guid":{"rendered":"http:\/\/www.allerin.com\/blog\/?p=1031"},"modified":"2016-05-12T14:50:23","modified_gmt":"2016-05-12T09:20:23","slug":"multi-tenancy-in-rails","status":"publish","type":"post","link":"https:\/\/www.allerin.com\/blog\/multi-tenancy-in-rails\/","title":{"rendered":"Multi-tenancy in Rails"},"content":{"rendered":"<p>What Multi-tenancy means? In simple definition it is a principle in software architecture where a single instance of the application serves multiple client organizations.<\/p>\n<p>Here client organizations are considered as a tenant. In\u00a0a multi-tenant architecture, application is designed virtually to partition its data and configuration so that each client organization works with a customized virtual application instance.<\/p>\n<p>Multi-tenant application mainly has three type of users.<\/p>\n<p><span style=\"text-decoration: underline;\">Admins:<\/span> These are the clients who own the site and have top-level access.<\/p>\n<p><span style=\"text-decoration: underline;\">Managers:<\/span> These are the resources from the company. They manage the projects and users at the company level.<\/p>\n<p><span style=\"text-decoration: underline;\">Users:<\/span> These are the end users of this application. Here each page will be accessible to users depending on their authorizations.<\/p>\n<p><strong>Advantages of Multi-tenancy:<\/strong><\/p>\n<ol>\n<li><strong>Cost savings:<\/strong> Multi-tenancy allows for cost savings by considering resources and softwares used in the application. Cost and maintenance will increased when multiplied by many customers, especially if the customers are small. Multi-tenancy reduces this overhead by sharing same power resources and softwares. Software requires the licenses and support which will increases the cost if it needs to buy for every customer (single-tenancy). Shared infrastructure leads to lower costs.<\/li>\n<li><strong>Scalability:<\/strong> A multi-tenant architecture makes it easy to increase capacity when more strength &amp; power is required. When adding new hardware to the platform, the total capacity of the entire system increases\u00a0and\u00a0becomes more scalable, not for just a single client but for all the associated clients. Adding the features for a single client makes it available to other clients.<\/li>\n<li><strong>Service:<\/strong> In multi-tenant application monitoring and administration will be required for one platform instead of managing different sets for each client. A multi-tenant SaaS provider can deliver more efficient and effective service and support, including troubleshooting and problem resolution.<\/li>\n<li><strong>Upgrades:<\/strong> Upgrading the softwares version or system resources for multi-tenant applications (like dbs, servers, h\/w resources etc.) are easy since there is a single, centralized place to go to make upgradation, installation etc.<\/li>\n<\/ol>\n<p>Multi-tenancy in rails can be achieved with many architectures, some of them are listed below. Main feature in multi-tenancy should be there access privacy between all the resources(Admin, Manager and User.)<\/p>\n<p><strong>Using namespaces<\/strong><\/p>\n<p><span style=\"text-decoration: underline;\"># Admin controller<\/span><\/p>\n<pre>class Admin::ProjectsController &lt; ApplicationController\r\n  before_action :authenticate_admin_user! # for devise gem\r\n  def show\r\n    @project = Project.find(params[:id])\r\n  end\r\nend\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p><span style=\"text-decoration: underline;\"># User controller<\/span><\/p>\n<pre>class ProjectsController &lt; ApplicationController\r\n  before_action :authenticate_user!\r\n  def show\r\n    # here projects are associated with a user as many associations.\r\n    @project = current_user.projects.find(params[:id]) \r\n  end\r\nend\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p><span style=\"text-decoration: underline;\"># Management controller<\/span><\/p>\n<pre>class Management::ProjectsController &lt; ApplicationController\r\n  before_action :authenticate_company_user!\r\n  before_action :find_company\r\n  \r\n  def show\r\n   # here projects are associated with the company as many association \r\n   # or through:users and user belongs to the company.\r\n   @project = company.projects.find(params[:id])\r\n  end\r\n\r\nprivate\r\n  # can be moved to more appropriate place\r\n  def find_company\r\n    @company = company_user.company\r\n  end\r\nend\r\n<\/pre>\n<p><strong>Using default_scope<\/strong> <em>(Ryan Bates Multi-tenancy with Scopes)<\/em><\/p>\n<p><span style=\"text-decoration: underline;\">Consider below schema:<\/span><\/p>\n<pre>class Company &lt; ActiveRecord::Base\r\n  attr_accessible :name\r\n  cattr_accessor :current_id\r\nend\r\n\r\nclass ApplicationController\r\n  around_action :scope_current_company\r\n  private\r\n  def scope_current_company\r\n    Company.current_id = current_tenant.id\r\n    yield\r\n    ensure\r\n    Company.current_id = nil\r\n  end\r\nend\r\n\r\nclass User &lt; ActiveRecord::Base\r\n  default_scope { where (:company_id =&gt; Company.current_id) }\r\nend\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p>Above approach might not be feasible as it is extensively depends on class variable and if we not able to manage class variables as per thread.<\/p>\n<p>Above can be achieved by using gem <strong>act_as_tenant<\/strong> <a href=\"https:\/\/github.com\/ErwinM\/acts_as_tenant\" target=\"_blank\">https:\/\/github.com\/ErwinM\/acts_as_tenant<\/a><\/p>\n<p><strong>Separate Database<\/strong> (<em>Apartments Method<\/em>)<\/p>\n<p>In\u00a0gem apartment <a href=\"https:\/\/github.com\/influitive\/apartment\" target=\"_blank\">https:\/\/github.com\/influitive\/apartment<\/a>, we can use separate databases for each company. This makes system more secure by considering data will not be sharable to other company.<\/p>\n<p><strong>Shared Database, Shared Schema<\/strong> (<em>Using scopes and Model partitioning<\/em>)<\/p>\n<p>Sometimes we require that data of two companies can be shared within their users. We can achieve multi-tenancy by using scopes.<\/p>\n<p><span style=\"text-decoration: underline;\">Consider below schema:<\/span><\/p>\n<p>User |id|name|email|&#8230;|tenant_id|<\/p>\n<p>Project |id|name|&#8230;|tenant_id|<\/p>\n<p>The shared schema approach has the lowest hardware and backup costs, because it allows you to serve the largest number of tenants per database server. However, because multiple tenants share the same database tables, and this approach may require additional development effort in the area of security, to ensure that tenants can never access other tenant&#8217;s data, even in the event of unexpected bugs or attacks.<\/p>\n<p><span style=\"text-decoration: underline;\">Advantage of the above approach is &#8211;<\/span><\/p>\n<ul>\n<li>* No special deployment or infrastructure required.<\/li>\n<\/ul>\n<p><span style=\"text-decoration: underline;\">Disadvantage would be &#8211;<\/span><\/p>\n<ul>\n<li>* Relies on application query logic.<\/li>\n<li>* Does not inherently prevent data leakage.<\/li>\n<li>* Scaling with performance.<\/li>\n<\/ul>\n<p>To achieve above, we can use gem <strong>multitenant<\/strong> <a href=\"https:\/\/github.com\/wireframe\/multitenant\" target=\"_blank\">https:\/\/github.com\/wireframe\/multitenant <\/a><\/p>\n<p>When we are dealing with multi-tenant architecture we always need to consider the bug and exceptions. As this will not only affect one customer of tenant, it will affect functionalities of all the customers of the architecture.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>What Multi-tenancy means, In simple definition it is a principle in software architecture where a single instance of the software serves multiple client organizations. Here client organizations are considered as a tenant. With a multi-tenant architecture, the software application is designed virtually to partition its data and configuration so that each client organization works with a customized virtual application instance.<\/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":[],"class_list":["post-1031","post","type-post","status-publish","format-standard","hentry","category-technology"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.5 (Yoast SEO v27.8) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Multi-tenancy in Rails (Ruby on Rails)<\/title>\n<meta name=\"description\" content=\"Here I talk about several methods used for Multi-tenancy in Rails (Ruby on Rails), what I learned during my programming career in rails.\" \/>\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\/multi-tenancy-in-rails\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Multi-tenancy in Rails\" \/>\n<meta property=\"og:description\" content=\"What Multi-tenancy means, In simple definition it is a principle in software architecture where a single instance of the software serves multiple client organizations. Here client organizations are considered as a tenant. With a multi-tenant architecture, the software application is designed virtually to partition its data and configuration so that each client organization works with a customized virtual application instance.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.allerin.com\/blog\/multi-tenancy-in-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-07-21T07:23:01+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2016-05-12T09:20:23+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=\"4 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.allerin.com\\\/blog\\\/multi-tenancy-in-rails\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.allerin.com\\\/blog\\\/multi-tenancy-in-rails\\\/\"},\"author\":{\"name\":\"Nitesh Varma\",\"@id\":\"https:\\\/\\\/www.allerin.com\\\/blog\\\/#\\\/schema\\\/person\\\/62051995e859f22af8935f2c15a7f00d\"},\"headline\":\"Multi-tenancy in Rails\",\"datePublished\":\"2014-07-21T07:23:01+00:00\",\"dateModified\":\"2016-05-12T09:20:23+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.allerin.com\\\/blog\\\/multi-tenancy-in-rails\\\/\"},\"wordCount\":651,\"commentCount\":3,\"publisher\":{\"@id\":\"https:\\\/\\\/www.allerin.com\\\/blog\\\/#organization\"},\"articleSection\":[\"Technology\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.allerin.com\\\/blog\\\/multi-tenancy-in-rails\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.allerin.com\\\/blog\\\/multi-tenancy-in-rails\\\/\",\"url\":\"https:\\\/\\\/www.allerin.com\\\/blog\\\/multi-tenancy-in-rails\\\/\",\"name\":\"Multi-tenancy in Rails (Ruby on Rails)\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.allerin.com\\\/blog\\\/#website\"},\"datePublished\":\"2014-07-21T07:23:01+00:00\",\"dateModified\":\"2016-05-12T09:20:23+00:00\",\"description\":\"Here I talk about several methods used for Multi-tenancy in Rails (Ruby on Rails), what I learned during my programming career in rails.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.allerin.com\\\/blog\\\/multi-tenancy-in-rails\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.allerin.com\\\/blog\\\/multi-tenancy-in-rails\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.allerin.com\\\/blog\\\/multi-tenancy-in-rails\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.allerin.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Multi-tenancy in 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":"Multi-tenancy in Rails (Ruby on Rails)","description":"Here I talk about several methods used for Multi-tenancy in Rails (Ruby on Rails), what I learned during my programming career in rails.","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\/multi-tenancy-in-rails\/","og_locale":"en_US","og_type":"article","og_title":"Multi-tenancy in Rails","og_description":"What Multi-tenancy means, In simple definition it is a principle in software architecture where a single instance of the software serves multiple client organizations. Here client organizations are considered as a tenant. With a multi-tenant architecture, the software application is designed virtually to partition its data and configuration so that each client organization works with a customized virtual application instance.","og_url":"https:\/\/www.allerin.com\/blog\/multi-tenancy-in-rails\/","og_site_name":"Artificial Intelligence, ROBOTICS, AUTOMATION","article_publisher":"https:\/\/www.facebook.com\/allerintech","article_published_time":"2014-07-21T07:23:01+00:00","article_modified_time":"2016-05-12T09:20:23+00:00","author":"Nitesh Varma","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Nitesh Varma","Est. reading time":"4 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.allerin.com\/blog\/multi-tenancy-in-rails\/#article","isPartOf":{"@id":"https:\/\/www.allerin.com\/blog\/multi-tenancy-in-rails\/"},"author":{"name":"Nitesh Varma","@id":"https:\/\/www.allerin.com\/blog\/#\/schema\/person\/62051995e859f22af8935f2c15a7f00d"},"headline":"Multi-tenancy in Rails","datePublished":"2014-07-21T07:23:01+00:00","dateModified":"2016-05-12T09:20:23+00:00","mainEntityOfPage":{"@id":"https:\/\/www.allerin.com\/blog\/multi-tenancy-in-rails\/"},"wordCount":651,"commentCount":3,"publisher":{"@id":"https:\/\/www.allerin.com\/blog\/#organization"},"articleSection":["Technology"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.allerin.com\/blog\/multi-tenancy-in-rails\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.allerin.com\/blog\/multi-tenancy-in-rails\/","url":"https:\/\/www.allerin.com\/blog\/multi-tenancy-in-rails\/","name":"Multi-tenancy in Rails (Ruby on Rails)","isPartOf":{"@id":"https:\/\/www.allerin.com\/blog\/#website"},"datePublished":"2014-07-21T07:23:01+00:00","dateModified":"2016-05-12T09:20:23+00:00","description":"Here I talk about several methods used for Multi-tenancy in Rails (Ruby on Rails), what I learned during my programming career in rails.","breadcrumb":{"@id":"https:\/\/www.allerin.com\/blog\/multi-tenancy-in-rails\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.allerin.com\/blog\/multi-tenancy-in-rails\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.allerin.com\/blog\/multi-tenancy-in-rails\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.allerin.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Multi-tenancy in 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\/1031","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=1031"}],"version-history":[{"count":15,"href":"https:\/\/www.allerin.com\/blog\/wp-json\/wp\/v2\/posts\/1031\/revisions"}],"predecessor-version":[{"id":1388,"href":"https:\/\/www.allerin.com\/blog\/wp-json\/wp\/v2\/posts\/1031\/revisions\/1388"}],"wp:attachment":[{"href":"https:\/\/www.allerin.com\/blog\/wp-json\/wp\/v2\/media?parent=1031"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.allerin.com\/blog\/wp-json\/wp\/v2\/categories?post=1031"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.allerin.com\/blog\/wp-json\/wp\/v2\/tags?post=1031"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}