{"id":6257,"date":"2019-05-23T20:01:56","date_gmt":"2019-05-23T20:01:56","guid":{"rendered":"https:\/\/blog-stg.cheesecakelabs.com\/blog\/mvvm-in-ios\/"},"modified":"2022-07-01T17:16:18","modified_gmt":"2022-07-01T17:16:18","slug":"mvvm-in-ios","status":"publish","type":"post","link":"https:\/\/blog-stg.cheesecakelabs.com\/br\/mvvm-in-ios\/","title":{"rendered":"MVVM in iOS"},"content":{"rendered":"<p><span style=\"font-weight: 400;\">One of my biggest concerns as a developer is how a project is structured. Defining a good and clean architecture with helpful names and nice design patterns is very important. It helps you and other developers to easily understand how different components of the code connect to each other and makes our lives easier in the long term. It&#8217;s also very important to keep a good documentation about it. Always keep the README.md file updated. It helps new developers a lot.<\/span><\/p>\n<p><!--more--><\/p>\n<p><img decoding=\"async\" class=\"size-full wp-image-6252 aligncenter\" src=\"https:\/\/ckl-website-static.s3.amazonaws.com\/wp-content\/uploads\/2019\/05\/image3.gif\" alt=\"Gif of four megazords running.\" width=\"500\" height=\"375\"><\/p>\n<p><span style=\"font-weight: 400;\">Here at Cheesecake Labs we care a lot about how the projects are structured. This is very important when working in teams in the same codebase. This way everybody codes in the same style. Keeping code readable for everybody during the whole project.<\/span><\/p>\n<p><a href=\"https:\/\/developer.android.com\/topic\/libraries\/architecture\"><span style=\"font-weight: 400;\">Android Architecture Components<\/span><\/a><span style=\"font-weight: 400;\"> brought a new way to connect the views to the backend of Android projects: the &#8220;ViewModel&#8221;. The name explains itself. It&#8217;s an intermediary layer that connects the View (UI) to the Model (Business logic, APIs and persistency). It makes the structure of Android projects more simple to understand and it is also a good way to keep view and business logic decoupled, organized and easy to test.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">MVVM is not mentioned in Google&#8217;s documentation, but the implementation of the Android ViewModels fits very well in the MVVM design pattern. So that&#8217;s what we decided to use.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">MVVM worked so well in Android projects that we decided to use it in iOS projects too. And the results have been very good so far.<\/span><\/p>\n<h1><span style=\"font-weight: 400;\">MVVMC<\/span><\/h1>\n<p><span style=\"font-weight: 400;\">ViewModel is not a new concept. It&#8217;s the main part of the MVVM design pattern that was first introduced in 2005 by Josh Gossman in this <\/span><a href=\"https:\/\/blogs.msdn.microsoft.com\/johngossman\/2005\/10\/08\/introduction-to-modelviewviewmodel-pattern-for-building-wpf-apps\/\"><span style=\"font-weight: 400;\">post<\/span><\/a><span style=\"font-weight: 400;\"> at Microsoft&#8217;s blog. It was created to be used as a design pattern in .NET applications, but of course we can use it anywhere &#8211; including Android and iOS projects. Each platform has its implementation particularities, so for iOS we are using the way the Runtastic team introduced in <\/span><a href=\"https:\/\/www.runtastic.com\/blog\/en\/mvvmc-adapting-the-mvvm-design-pattern-at-runtastic\/\"><span style=\"font-weight: 400;\">this blog post<\/span><\/a><span style=\"font-weight: 400;\">. The MVVMC.<\/span><\/p>\n<p><b>MVVMC<\/b><span style=\"font-weight: 400;\"> is made of five main layers:<\/span><\/p>\n<p><img decoding=\"async\" class=\"size-full wp-image-6254 aligncenter\" src=\"https:\/\/ckl-website-static.s3.amazonaws.com\/wp-content\/uploads\/2019\/05\/image5.png\" alt=\"Image of MVVMC five main layers connected to each other.\" width=\"806\" height=\"459\" srcset=\"https:\/\/ckl-website-static.s3.amazonaws.com\/wp-content\/uploads\/2019\/05\/image5.png 806w, https:\/\/ckl-website-static.s3.amazonaws.com\/wp-content\/uploads\/2019\/05\/image5-768x437.png 768w\" sizes=\"(max-width: 806px) 100vw, 806px\" \/><\/p>\n<h2><span style=\"font-weight: 400;\">View<\/span><\/h2>\n<p><span style=\"font-weight: 400;\">This is the UI. It <\/span><b>shows information<\/b><span style=\"font-weight: 400;\"> to the user and <\/span><b>tells the ViewModel about User actions<\/b><span style=\"font-weight: 400;\">. It should not know about ViewModel implementation, so the ViewModel can be unit tested with a &#8220;mocked&#8221; view. There are a lot of ways to connect these layers. Here is an example using simple delegates:<\/span><\/p>\n<pre class=\"language-swift\"><code class=\"language-swift\">class RocketLaunchViewController: UIViewController {\n     var viewModel: ArticlesListViewModel?   \n     \n     override func viewDidLoad() {\n          super.viewDidLoad()\n          viewModel?.onViewDidLoad()\n     }\n     \n     @IBAction func didTapLaunchButton(_ sender: Any) {\n          viewModel?.onLaunchButtonTapped()\n     }\n}\n \nextension RocketLaunchViewController: RocketLaunchViewDelegate {\n     func showSuccessMessage() {\n          \/\/Show success message\n     }\n}<\/code><\/pre>\n<h2><span style=\"font-weight: 400;\">Model<\/span><\/h2>\n<p><span style=\"font-weight: 400;\">The model is an abstraction of the app data. Usually we define entities that represents the objects and business logic that define how these entities relate to themselves. Each project has a particular model structure that can be fetched from an API, persisted in the database, sent to a Bluetooth device, etc\u2026 Model layer is shared between all modules of the project, so it&#8217;s important to keep this layer consistent and safe.<\/span><\/p>\n<h2><span style=\"font-weight: 400;\">ViewModel<\/span><\/h2>\n<p><img decoding=\"async\" class=\"alignnone size-full wp-image-6258 aligncenter\" src=\"https:\/\/ckl-website-static.s3.amazonaws.com\/wp-content\/uploads\/2019\/05\/ezgif.com-optimize-1.gif\" alt=\"\" width=\"320\" height=\"240\"><\/p>\n<p><span style=\"font-weight: 400;\">This is the glue that makes all parts working together. The ViewModel is responsible for telling the View what should be shown to the user and to respond to whatever the user does in the UI. The ViewModel uses an Interactor to access the model layer and the Coordinator to communicate to other modules. Here is a small example:<\/span><\/p>\n<pre class=\"language-swift\"><code class=\"language-swift\">protocol RocketLaunchViewDelegate: class {\n     func showSuccessMessage()\n}\n \nclass RocketLaunchViewModel {\n     weak var view: RocketLaunchViewDelegate?\n     var interactor: RocketLaunchInteractor?\n     var coordinator: RocketLaunchCoordinator?\n\n     func onViewDidLoad() {\n          interactor?.fetchRockectData() { result in\n               if result.status == .success {\n                    self.view?.showSuccessMessage()\n               }\n          }\n     }\n\n     func onLaunchButtonTapped() {\n          coordinator?.showLaunchProgressModule()\n     }\n}<\/code><\/pre>\n<h2><span style=\"font-weight: 400;\">Interactor<\/span><\/h2>\n<p><span style=\"font-weight: 400;\">The interactor exposes the model layer to the ViewModel. Access to Database, API requests and other data that are external to the current module should be asked to the interactor by the ViewModel. Usually we create data access that is shared between all modules, like an API Manager, or Database Manager that concentrates logic that keep the data consistent. Interactor is the part that should communicate to these managers.<\/span><\/p>\n<h2><span style=\"font-weight: 400;\">Coordinator<\/span><\/h2>\n<p><span style=\"font-weight: 400;\">This part of the MVVMC pattern was added to handle communication between MVVMC modules. It is the way ViewModel uses to communicate and initiate other modules. This is also used to assemble a new MVVMC module. Code tells more than words, so:<\/span><\/p>\n<pre class=\"language-swift\"><code class=\"language-swift\">class RocketLaunchCoordinator {\n     var viewController: UIViewController?\n     \n     func initModule() -&gt; UIViewController {\n          let interactor = RocketLaunchInteractor()\n          let viewModel = RocketLaunchViewModel(coordinator: self, interactor: interactor)\n          let viewController = UIStoryboard.loadViewController() as RocketLaunchViewController\n          viewController.viewModel = viewModel\n          return viewController\n     }\n      \n     func showLaunchProgressModule() {\n          let viewController = LaunchProgressCoordinator().initModule()\n          viewController?.presentViewController(viewController, animated: true)\n     }\n}<\/code><\/pre>\n<p><span style=\"font-weight: 400;\">That&#8217;s it!<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><img decoding=\"async\" class=\"size-medium aligncenter\" src=\"https:\/\/i.imgur.com\/AiulNyn.gif?noredirect\" alt=\"Megazord transforming with lightnings around it. \" width=\"495\" height=\"495\"><\/p>\n<p><span style=\"font-weight: 400;\">MVVM is simple and we can maintain a design pattern that is similar in both mobile platform. It defines how things connect and keeps all the code in its place according to what they should be doing.<\/span><\/p>\n<h2><span style=\"font-weight: 400;\">Is it better than VIPER?<\/span><\/h2>\n<p><span style=\"font-weight: 400;\">Yes &#8211; this is my short answer!<\/span><\/p>\n<p><span style=\"font-weight: 400;\">The long explanation is: for some time VIPER has been our design pattern to be used as the default structure of the modules of mobile apps at CKL. VIPER has brought established solutions to some common issues we have being through. It decouples things, so they can be tested. And defines responsibilities for every layer, so we know where to put code, avoiding the famous Massive View Controllers.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">So, what&#8217;s wrong with it?<\/span><\/p>\n<p><span style=\"font-weight: 400;\">VIPER has too many layers. This started to become a problem. Every new module needs a big set of classes, even when the module is a simple one, like a login page. There are too many things we need to plug and a lot of abstraction layers to understand.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">MVVM brings all the testability and decoupling we need in a smaller and more simple to understand pattern. MVVM core has only 3 layers. And the name of these layers explain themselves. Of course we added Coordinator and Interactors to the set. But the core of the pattern is simple and the same for both platforms.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Also, I don&#8217;t like snakes. ????<\/span><\/p>\n<p><img decoding=\"async\" class=\"alignnone size-full wp-image-6255 aligncenter\" src=\"https:\/\/ckl-website-static.s3.amazonaws.com\/wp-content\/uploads\/2019\/05\/image41.gif\" alt=\"Gif of a Megazord holding a sword.\" width=\"500\" height=\"376\"><\/p>\n<h2><span style=\"font-weight: 400;\">References<\/span><\/h2>\n<ul>\n<li style=\"font-weight: 400;\"><a href=\"https:\/\/medium.com\/developermind\/blurring-the-lines-between-mvvm-and-viper-dcb3dc9815ac\"><span style=\"font-weight: 400;\">https:\/\/medium.com\/developermind\/blurring-the-lines-between-mvvm-and-viper-dcb3dc9815ac<\/span><\/a><\/li>\n<li style=\"font-weight: 400;\"><a href=\"https:\/\/blogs.msdn.microsoft.com\/johngossman\/2005\/10\/08\/introduction-to-modelviewviewmodel-pattern-for-building-wpf-apps\/\"><span style=\"font-weight: 400;\">https:\/\/blogs.msdn.microsoft.com\/johngossman\/2005\/10\/08\/introduction-to-modelviewviewmodel-pattern-for-building-wpf-apps\/<\/span><\/a><\/li>\n<li style=\"font-weight: 400;\"><a href=\"https:\/\/developer.android.com\/topic\/libraries\/architecture\"><span style=\"font-weight: 400;\">https:\/\/developer.android.com\/topic\/libraries\/architecture<\/span><\/a><\/li>\n<li style=\"font-weight: 400;\"><a href=\"https:\/\/www.runtastic.com\/blog\/en\/mvvmc-adapting-the-mvvm-design-pattern-at-runtastic\/\"><span style=\"font-weight: 400;\">https:\/\/www.runtastic.com\/blog\/en\/mvvmc-adapting-the-mvvm-design-pattern-at-runtastic\/<\/span><\/a><\/li>\n<li style=\"font-weight: 400;\"><a href=\"https:\/\/blog-stg.cheesecakelabs.com\/ios-project-architecture-using-viper\/\"><span style=\"font-weight: 400;\">https:\/\/blog-stg.cheesecakelabs.com\/blog\/ios-project-architecture-using-viper\/<\/span><\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>One of my biggest concerns as a developer is how a project is structured. Defining a good and clean architecture with helpful names and nice design patterns is very important. It helps you and other developers to easily understand how different components of the code connect to each other and makes our lives easier in [&hellip;]<\/p>\n","protected":false},"author":65,"featured_media":9406,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[471,1163],"tags":[1157,1156,1158],"class_list":["post-6257","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-engenharia","category-process-br","tag-tag-ios-development-br","tag-tag-mobile-br","tag-tag-mobile-development-br"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v21.1 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>MVVM in iOS | Cheesecake Labs<\/title>\n<meta name=\"robots\" content=\"noindex, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<meta property=\"og:locale\" content=\"pt_BR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"MVVM in iOS | Cheesecake Labs\" \/>\n<meta property=\"og:description\" content=\"One of my biggest concerns as a developer is how a project is structured. Defining a good and clean architecture with helpful names and nice design patterns is very important. It helps you and other developers to easily understand how different components of the code connect to each other and makes our lives easier in [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/blog-stg.cheesecakelabs.com\/br\/mvvm-in-ios\/\" \/>\n<meta property=\"og:site_name\" content=\"Cheesecake Labs\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/cheesecakelabs\" \/>\n<meta property=\"article:published_time\" content=\"2019-05-23T20:01:56+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2022-07-01T17:16:18+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/ckl-website-static.s3.amazonaws.com\/wp-content\/uploads\/2019\/05\/Blogpost_Ricardo.png\" \/>\n\t<meta property=\"og:image:width\" content=\"2000\" \/>\n\t<meta property=\"og:image:height\" content=\"720\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Cheesecake Labs\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@cheesecakelabs\" \/>\n<meta name=\"twitter:site\" content=\"@cheesecakelabs\" \/>\n<meta name=\"twitter:label1\" content=\"Escrito por\" \/>\n\t<meta name=\"twitter:data1\" content=\"\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. tempo de leitura\" \/>\n\t<meta name=\"twitter:data2\" content=\"5 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/blog-stg.cheesecakelabs.com\/br\/mvvm-in-ios\/\",\"url\":\"https:\/\/blog-stg.cheesecakelabs.com\/br\/mvvm-in-ios\/\",\"name\":\"MVVM in iOS | Cheesecake Labs\",\"isPartOf\":{\"@id\":\"https:\/\/blog-stg.cheesecakelabs.com\/br\/#website\"},\"datePublished\":\"2019-05-23T20:01:56+00:00\",\"dateModified\":\"2022-07-01T17:16:18+00:00\",\"author\":{\"@type\":\"person\",\"name\":\"Ricardo Gehrke Filho\"},\"breadcrumb\":{\"@id\":\"https:\/\/blog-stg.cheesecakelabs.com\/br\/mvvm-in-ios\/#breadcrumb\"},\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/blog-stg.cheesecakelabs.com\/br\/mvvm-in-ios\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/blog-stg.cheesecakelabs.com\/br\/mvvm-in-ios\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/blog-stg.cheesecakelabs.com\/br\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"MVVM in iOS\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/blog-stg.cheesecakelabs.com\/br\/#website\",\"url\":\"https:\/\/blog-stg.cheesecakelabs.com\/br\/\",\"name\":\"Cheesecake Labs\",\"description\":\"Empresa de desenvolvimento e design de aplicativos mobile &amp; web que est\u00e1 reinventando o desenvolvimento de produtos com times remotos. N\u00f3s desenvolvemos aplicativos iOS, Android e aplica\u00e7\u00f5es Web com as melhores empresas dos EUA, do Brasil e do mundo.\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/blog-stg.cheesecakelabs.com\/br\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"pt-BR\"},{\"@type\":\"Person\",\"name\":\"Ricardo Gehrke Filho\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\/\/blog-stg.cheesecakelabs.com\/br\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/ckl-website-static.s3.amazonaws.com\/wp-content\/uploads\/2017\/09\/ricardo-300x300.jpg\",\"contentUrl\":\"https:\/\/ckl-website-static.s3.amazonaws.com\/wp-content\/uploads\/2017\/09\/ricardo-300x300.jpg\",\"caption\":\"Ricardo Gehrke Filho\"},\"description\":\"10 years of experience in Marketing and Sales in the Technology sector. My main purpose is help, support and structure efficient operations and also develop independent and multidisciplinary teams.\",\"url\":\"https:\/\/blog-stg.cheesecakelabs.com\/br\/\/autor\/ricardo-gehrke-filho\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"MVVM in iOS | Cheesecake Labs","robots":{"index":"noindex","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"og_locale":"pt_BR","og_type":"article","og_title":"MVVM in iOS | Cheesecake Labs","og_description":"One of my biggest concerns as a developer is how a project is structured. Defining a good and clean architecture with helpful names and nice design patterns is very important. It helps you and other developers to easily understand how different components of the code connect to each other and makes our lives easier in [&hellip;]","og_url":"https:\/\/blog-stg.cheesecakelabs.com\/br\/mvvm-in-ios\/","og_site_name":"Cheesecake Labs","article_publisher":"https:\/\/www.facebook.com\/cheesecakelabs","article_published_time":"2019-05-23T20:01:56+00:00","article_modified_time":"2022-07-01T17:16:18+00:00","og_image":[{"width":2000,"height":720,"url":"https:\/\/ckl-website-static.s3.amazonaws.com\/wp-content\/uploads\/2019\/05\/Blogpost_Ricardo.png","type":"image\/png"}],"author":"Cheesecake Labs","twitter_card":"summary_large_image","twitter_creator":"@cheesecakelabs","twitter_site":"@cheesecakelabs","twitter_misc":{"Escrito por":null,"Est. tempo de leitura":"5 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/blog-stg.cheesecakelabs.com\/br\/mvvm-in-ios\/","url":"https:\/\/blog-stg.cheesecakelabs.com\/br\/mvvm-in-ios\/","name":"MVVM in iOS | Cheesecake Labs","isPartOf":{"@id":"https:\/\/blog-stg.cheesecakelabs.com\/br\/#website"},"datePublished":"2019-05-23T20:01:56+00:00","dateModified":"2022-07-01T17:16:18+00:00","author":{"@type":"person","name":"Ricardo Gehrke Filho"},"breadcrumb":{"@id":"https:\/\/blog-stg.cheesecakelabs.com\/br\/mvvm-in-ios\/#breadcrumb"},"inLanguage":"pt-BR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/blog-stg.cheesecakelabs.com\/br\/mvvm-in-ios\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/blog-stg.cheesecakelabs.com\/br\/mvvm-in-ios\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/blog-stg.cheesecakelabs.com\/br\/"},{"@type":"ListItem","position":2,"name":"MVVM in iOS"}]},{"@type":"WebSite","@id":"https:\/\/blog-stg.cheesecakelabs.com\/br\/#website","url":"https:\/\/blog-stg.cheesecakelabs.com\/br\/","name":"Cheesecake Labs","description":"Empresa de desenvolvimento e design de aplicativos mobile &amp; web que est\u00e1 reinventando o desenvolvimento de produtos com times remotos. N\u00f3s desenvolvemos aplicativos iOS, Android e aplica\u00e7\u00f5es Web com as melhores empresas dos EUA, do Brasil e do mundo.","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/blog-stg.cheesecakelabs.com\/br\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"pt-BR"},{"@type":"Person","name":"Ricardo Gehrke Filho","image":{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/blog-stg.cheesecakelabs.com\/br\/#\/schema\/person\/image\/","url":"https:\/\/ckl-website-static.s3.amazonaws.com\/wp-content\/uploads\/2017\/09\/ricardo-300x300.jpg","contentUrl":"https:\/\/ckl-website-static.s3.amazonaws.com\/wp-content\/uploads\/2017\/09\/ricardo-300x300.jpg","caption":"Ricardo Gehrke Filho"},"description":"10 years of experience in Marketing and Sales in the Technology sector. My main purpose is help, support and structure efficient operations and also develop independent and multidisciplinary teams.","url":"https:\/\/blog-stg.cheesecakelabs.com\/br\/\/autor\/ricardo-gehrke-filho\/"}]}},"_links":{"self":[{"href":"https:\/\/blog-stg.cheesecakelabs.com\/br\/wp-json\/wp\/v2\/posts\/6257","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog-stg.cheesecakelabs.com\/br\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog-stg.cheesecakelabs.com\/br\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog-stg.cheesecakelabs.com\/br\/wp-json\/wp\/v2\/users\/65"}],"replies":[{"embeddable":true,"href":"https:\/\/blog-stg.cheesecakelabs.com\/br\/wp-json\/wp\/v2\/comments?post=6257"}],"version-history":[{"count":1,"href":"https:\/\/blog-stg.cheesecakelabs.com\/br\/wp-json\/wp\/v2\/posts\/6257\/revisions"}],"predecessor-version":[{"id":10211,"href":"https:\/\/blog-stg.cheesecakelabs.com\/br\/wp-json\/wp\/v2\/posts\/6257\/revisions\/10211"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog-stg.cheesecakelabs.com\/br\/wp-json\/wp\/v2\/media\/9406"}],"wp:attachment":[{"href":"https:\/\/blog-stg.cheesecakelabs.com\/br\/wp-json\/wp\/v2\/media?parent=6257"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog-stg.cheesecakelabs.com\/br\/wp-json\/wp\/v2\/categories?post=6257"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog-stg.cheesecakelabs.com\/br\/wp-json\/wp\/v2\/tags?post=6257"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}