{"id":3813,"date":"2021-09-02T15:26:04","date_gmt":"2021-09-02T15:26:04","guid":{"rendered":"https:\/\/ionicframework.com\/blog\/?p=3813"},"modified":"2021-10-05T15:59:08","modified_gmt":"2021-10-05T15:59:08","slug":"ionic-react-and-realm","status":"publish","type":"post","link":"https:\/\/ionic.io\/blog\/ionic-react-and-realm","title":{"rendered":"Ionic React and Realm"},"content":{"rendered":"<p>Building an app these days often requires some kind of data layer, whether storing data locally using LocalStorage or using some remote database solution. In this blog post, we will look at Realm, from MongoDB, as our storage solution for our web app and discover how we can start to make use of it in an Ionic React app, with either GraphQL or direct DB operations. But before we look at the code, let&#8217;s understand what Realm is and how it relates to MongoDB.<\/p>\n<p><!--more--><\/p>\n<h2>What Is Realm?<\/h2>\n<p>In the simplest terms, Realm is a platform made up of two parts. One is a local database solution for mobile that is an alternative to using something like SQLite. Realm will store the data locally on the device, but also sync it back with a MongoDB Atlas instance. Realm also offers a hosted application service that can handle data syncing across clients, as well as serverless functions for actions like authentication.<\/p>\n<p>For the Web SDK, Realm makes heavy use of the Atlas data layer. Instead of interacting with a local store, all the read\/write operations are performed on the Atlas instance directly. Realm&#8217;s serverless functions are still used for actions like authentication and user management.<\/p>\n<p>In our app, we&#8217;ll use Ionic and React to interact with a Realm\/Atlas instance and make a quick task tracker app. There are some prerequisites involved, but the Mongo docs cover everything <a href=\"https:\/\/docs.mongodb.com\/realm\/tutorial\/realm-app\/\">in this excellent page<\/a>. Following this tutorial will have you set up a free Atlas Database cluster and a free Realm hosted application.<\/p>\n<p>When your database and hosted app has been set up, you can clone the project below and play around with it.<\/p>\n<pre><code class=\"language-bash\">git clone https:\/\/github.com\/mhartington\/ionic-realm-demo\ncd ionic-realm-demo\n# Optionally check out the graphql-less version\ngit checkout graphql-less\nnpm install\nionic serve\n<\/code><\/pre>\n<p>With all the setup taken care of, let&#8217;s actually build something.<\/p>\n<h2>Accessing Realm From Your App<\/h2>\n<p>To start accessing Realm in your app, we first must make sure the Realm instance is available. To do so, we&#8217;re going to make use of React&#8217;s Context API and hooks. In the <code>src<\/code> directory, there is a <code>Realm.tsx<\/code> file, let&#8217;s open that up.<\/p>\n<pre><code class=\"language-ts\">import { createContext, useContext, useEffect, useState } from &#039;react&#039;;\nimport * as Realm from &#039;realm-web&#039;;\n\nconst RealmAppContext = createContext&lt;Partial&lt;Realm.App&gt;&gt;({});\n\nexport const useRealmApp = () =&gt; {\n  const app = useContext(RealmAppContext);\n  if (!app) {\n    throw new Error( `You must call useRealmApp() inside of a &lt;RealmAppProvider \/&gt;`);\n  }\n  return app;\n};\n\nexport const RealmAppProvider = ({ appId, children, }: { appId: any; children: JSX.Element; }) =&gt; {\n  const [app, setApp] = useState(new Realm.App(appId));\n  const [currentUser, setCurrentUser] = useState(app.currentUser);\n\n  useEffect(() =&gt; {\n    setApp(new Realm.App(appId));\n  }, [appId]);\n\n  const logIn = async (credentials: Realm.Credentials&lt;any&gt;) =&gt; {\n    const user = await app.logIn(credentials);\n    setCurrentUser(app.currentUser);\n    return user;\n  };\n  const logOut = async () =&gt; {\n    await app.currentUser?.logOut();\n    setCurrentUser(app.currentUser);\n  };\n\n  const wrapped = { ...app, currentUser, logIn, logOut };\n  return (\n    &lt;RealmAppContext.Provider value={wrapped}&gt;\n      {children}\n    &lt;\/RealmAppContext.Provider&gt;\n  );\n};\n<\/code><\/pre>\n<p>While this may seem like a lot, the basics of what is happening here can be broken down into three parts:<\/p>\n<ul>\n<li>Create &#8220;context&#8221; for our Realm instance<\/li>\n<li>Create a &#8220;provider&#8221; which will populate our context with the values needed<\/li>\n<li>Create a hook that exposes our context to the rest of the app.<\/li>\n<\/ul>\n<h3>Context<\/h3>\n<pre><code class=\"language-ts\">const RealmAppContext = createContext&lt;Partial&lt;Realm.App&gt;&gt;({});\n<\/code><\/pre>\n<p>Our context here is going to be a specialized React component whose value will be populated later on. This is where the Realm API will be mapped to and be exposed to our app.<\/p>\n<h3>Provider<\/h3>\n<p>The provider component is doing most of the heavy lifting here. When we use it, we set an app ID prop on it, and it will create a new Realm instance. We then create some state that is local to the component, like <code>app<\/code>, and <code>currentUser<\/code> to track when a user has logged in and out. This way we don&#8217;t have any accidental permission errors. We can provide some functions like <code>login<\/code> and <code>logout<\/code> to manage that currentUser and then create a wrapper around the built- in methods from Realm by destructuring the app instance and padding the new login\/logout functions.<\/p>\n<p>After the setup, we can finally render our context and set its value:<\/p>\n<pre><code class=\"language-ts\">return (\n  &lt;RealmAppContext.Provider value={wrapped}&gt;\n    {children}\n  &lt;\/RealmAppContext.Provider&gt;\n);\n<\/code><\/pre>\n<p><code>RealmAppContext<\/code> is our context from earlier, and all we&#8217;re doing is setting the value to be the wrapped Realm API we just created.<\/p>\n<h3>Hook<\/h3>\n<pre><code class=\"language-ts\">export const useRealmApp = () =&gt; {\n  const app = useContext(RealmAppContext);\n  if (!app) {\n    throw new Error(`You must call useRealmApp() inside of a &lt;RealmAppProvider \/&gt;`);\n  }\n  return app;\n};\n<\/code><\/pre>\n<p>With the provider and context handled, we now need a way to expose things at an application level. That is where our hook comes in. We can get our context by calling <code>useContext<\/code> and passing the context as an argument. Then, if the context has been set already, we can just return it!<\/p>\n<h2>Our Code In Action<\/h2>\n<p>With the hook, context, and provider established, we can start to see how our app&#8217;s functionality is set up. For instance, in <code>src\/pages\/Login.tsx<\/code>, to register or login to the app we use the <code>useRealmApp<\/code> hook and call our functions directly from it.<\/p>\n<pre><code class=\"language-ts\">&lt;br \/&gt;import { useRealmApp } from &#039;..\/Realm&#039;;\nimport * as Realm from &#039;realm-web&#039;;\n\nimport &#039;.\/Login.css&#039;;\nexport function Login() {\n\n  const app = useRealmApp();\n  const login = async () =&gt; {\n      await app.logIn!(\n        Realm.Credentials.emailPassword(loginInfo.email, loginInfo.password)\n      );\n  };\n  const register = async () =&gt; {\n    await app.emailPasswordAuth!.registerUser(\n      loginInfo.email,\n      loginInfo.password\n    );\n    await login();\n  };\n\n  return (...);\n}\n<\/code><\/pre>\n<p>With our hook, calling <code>logIn<\/code> will use the same app services that we created at the start of this. The best part is that we don&#8217;t need to cover every feature or Realm in the hook, just the stateful features that make sense to an app. We can still import Realm itself and call methods like <code>Realm.Credentials.emailPassword<\/code> to create the right payload for our login request.<\/p>\n<h2>Getting The Code<\/h2>\n<p>There&#8217;s a lot more going on in this app, and I highly suggest you check it out and start to know what you can do with Realm. To get the code, simply clone the repo and follow the <a href=\"https:\/\/docs.mongodb.com\/realm\/tutorial\/realm-app\/\">backend tutorial on Realm&#8217;s docs<\/a>.<\/p>\n<pre><code class=\"language-bash\">git clone https:\/\/github.com\/mhartington\/ionic-realm-demo\ncd ionic-realm-demo\n# Optionally check out the graphql-less version\ngit checkout graphql-less\nnpm install\nionic serve\n<\/code><\/pre>\n<p>There are two flavors of the app, one that uses GraphQL and one that uses the direct API from Atlas itself. Check out both versions and let us know which one is your favorite down in the comments \ud83d\ude00. Happy coding!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Building an app these days often requires some kind of data layer, whether storing data locally using LocalStorage or using some remote database solution. In this blog post, we will look at Realm, from MongoDB, as our storage solution for our web app and discover how we can start to make use of it in [&hellip;]<\/p>\n","protected":false},"author":5,"featured_media":3817,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"publish_to_discourse":"1","publish_post_category":"28","wpdc_auto_publish_overridden":"","wpdc_topic_tags":"","wpdc_pin_topic":"","wpdc_pin_until":"","discourse_post_id":"534019","discourse_permalink":"https:\/\/forum.ionicframework.com\/t\/ionic-react-and-realm\/215772","wpdc_publishing_response":"","wpdc_publishing_error":"","_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[124],"tags":[219,136,218],"class_list":["post-3813","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-tutorials","tag-mongodb","tag-react","tag-realm"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v23.0 (Yoast SEO v23.0) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Building an app with Ionic React and Realm - Ionic Blog<\/title>\n<meta name=\"description\" content=\"See how to build and Ionic React app and make use of Realm, from MongoDB, as a data layer for you mobile apps and PWAs.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/ionic.io\/blog\/ionic-react-and-realm\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Ionic React and Realm\" \/>\n<meta property=\"og:description\" content=\"See how to build and Ionic React app and make use of Realm, from MongoDB, as a data layer for you mobile apps and PWAs.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/ionic.io\/blog\/ionic-react-and-realm\" \/>\n<meta property=\"og:site_name\" content=\"Ionic Blog\" \/>\n<meta property=\"article:published_time\" content=\"2021-09-02T15:26:04+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2021-10-05T15:59:08+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2021\/09\/realm-ionic-feature-image.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1600\" \/>\n\t<meta property=\"og:image:height\" content=\"880\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Mike Hartington\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@mhartington\" \/>\n<meta name=\"twitter:site\" content=\"@ionicframework\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Mike Hartington\" \/>\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:\/\/ionic.io\/blog\/ionic-react-and-realm#article\",\"isPartOf\":{\"@id\":\"https:\/\/ionic.io\/blog\/ionic-react-and-realm\"},\"author\":{\"name\":\"Mike Hartington\",\"@id\":\"https:\/\/ionic.io\/blog\/#\/schema\/person\/c8c92b04d526adb925ea514c619a267b\"},\"headline\":\"Ionic React and Realm\",\"datePublished\":\"2021-09-02T15:26:04+00:00\",\"dateModified\":\"2021-10-05T15:59:08+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/ionic.io\/blog\/ionic-react-and-realm\"},\"wordCount\":824,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/ionic.io\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/ionic.io\/blog\/ionic-react-and-realm#primaryimage\"},\"thumbnailUrl\":\"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2021\/09\/realm-ionic-feature-image.png\",\"keywords\":[\"MongoDB\",\"react\",\"Realm\"],\"articleSection\":[\"Tutorials\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/ionic.io\/blog\/ionic-react-and-realm#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/ionic.io\/blog\/ionic-react-and-realm\",\"url\":\"https:\/\/ionic.io\/blog\/ionic-react-and-realm\",\"name\":\"Building an app with Ionic React and Realm - Ionic Blog\",\"isPartOf\":{\"@id\":\"https:\/\/ionic.io\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/ionic.io\/blog\/ionic-react-and-realm#primaryimage\"},\"image\":{\"@id\":\"https:\/\/ionic.io\/blog\/ionic-react-and-realm#primaryimage\"},\"thumbnailUrl\":\"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2021\/09\/realm-ionic-feature-image.png\",\"datePublished\":\"2021-09-02T15:26:04+00:00\",\"dateModified\":\"2021-10-05T15:59:08+00:00\",\"description\":\"See how to build and Ionic React app and make use of Realm, from MongoDB, as a data layer for you mobile apps and PWAs.\",\"breadcrumb\":{\"@id\":\"https:\/\/ionic.io\/blog\/ionic-react-and-realm#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/ionic.io\/blog\/ionic-react-and-realm\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/ionic.io\/blog\/ionic-react-and-realm#primaryimage\",\"url\":\"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2021\/09\/realm-ionic-feature-image.png\",\"contentUrl\":\"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2021\/09\/realm-ionic-feature-image.png\",\"width\":1600,\"height\":880},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/ionic.io\/blog\/ionic-react-and-realm#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/ionic.io\/blog\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Ionic React and Realm\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/ionic.io\/blog\/#website\",\"url\":\"https:\/\/ionic.io\/blog\/\",\"name\":\"ionic.io\/blog\",\"description\":\"Build amazing native and progressive web apps with the web\",\"publisher\":{\"@id\":\"https:\/\/ionic.io\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/ionic.io\/blog\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/ionic.io\/blog\/#organization\",\"name\":\"Ionic\",\"url\":\"https:\/\/ionic.io\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/ionic.io\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2020\/10\/white-on-color.png\",\"contentUrl\":\"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2020\/10\/white-on-color.png\",\"width\":1920,\"height\":854,\"caption\":\"Ionic\"},\"image\":{\"@id\":\"https:\/\/ionic.io\/blog\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/x.com\/ionicframework\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/ionic.io\/blog\/#\/schema\/person\/c8c92b04d526adb925ea514c619a267b\",\"name\":\"Mike Hartington\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/ionic.io\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2018\/08\/mike-headshot-2-smaller-150x150.png\",\"contentUrl\":\"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2018\/08\/mike-headshot-2-smaller-150x150.png\",\"caption\":\"Mike Hartington\"},\"description\":\"Director of Developer Relations\",\"sameAs\":[\"https:\/\/twitter.com\/mhartington\",\"https:\/\/x.com\/mhartington\"],\"url\":\"https:\/\/ionic.io\/blog\/author\/mike\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Building an app with Ionic React and Realm - Ionic Blog","description":"See how to build and Ionic React app and make use of Realm, from MongoDB, as a data layer for you mobile apps and PWAs.","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:\/\/ionic.io\/blog\/ionic-react-and-realm","og_locale":"en_US","og_type":"article","og_title":"Ionic React and Realm","og_description":"See how to build and Ionic React app and make use of Realm, from MongoDB, as a data layer for you mobile apps and PWAs.","og_url":"https:\/\/ionic.io\/blog\/ionic-react-and-realm","og_site_name":"Ionic Blog","article_published_time":"2021-09-02T15:26:04+00:00","article_modified_time":"2021-10-05T15:59:08+00:00","og_image":[{"width":1600,"height":880,"url":"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2021\/09\/realm-ionic-feature-image.png","type":"image\/png"}],"author":"Mike Hartington","twitter_card":"summary_large_image","twitter_creator":"@mhartington","twitter_site":"@ionicframework","twitter_misc":{"Written by":"Mike Hartington","Est. reading time":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/ionic.io\/blog\/ionic-react-and-realm#article","isPartOf":{"@id":"https:\/\/ionic.io\/blog\/ionic-react-and-realm"},"author":{"name":"Mike Hartington","@id":"https:\/\/ionic.io\/blog\/#\/schema\/person\/c8c92b04d526adb925ea514c619a267b"},"headline":"Ionic React and Realm","datePublished":"2021-09-02T15:26:04+00:00","dateModified":"2021-10-05T15:59:08+00:00","mainEntityOfPage":{"@id":"https:\/\/ionic.io\/blog\/ionic-react-and-realm"},"wordCount":824,"commentCount":0,"publisher":{"@id":"https:\/\/ionic.io\/blog\/#organization"},"image":{"@id":"https:\/\/ionic.io\/blog\/ionic-react-and-realm#primaryimage"},"thumbnailUrl":"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2021\/09\/realm-ionic-feature-image.png","keywords":["MongoDB","react","Realm"],"articleSection":["Tutorials"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/ionic.io\/blog\/ionic-react-and-realm#respond"]}]},{"@type":"WebPage","@id":"https:\/\/ionic.io\/blog\/ionic-react-and-realm","url":"https:\/\/ionic.io\/blog\/ionic-react-and-realm","name":"Building an app with Ionic React and Realm - Ionic Blog","isPartOf":{"@id":"https:\/\/ionic.io\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/ionic.io\/blog\/ionic-react-and-realm#primaryimage"},"image":{"@id":"https:\/\/ionic.io\/blog\/ionic-react-and-realm#primaryimage"},"thumbnailUrl":"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2021\/09\/realm-ionic-feature-image.png","datePublished":"2021-09-02T15:26:04+00:00","dateModified":"2021-10-05T15:59:08+00:00","description":"See how to build and Ionic React app and make use of Realm, from MongoDB, as a data layer for you mobile apps and PWAs.","breadcrumb":{"@id":"https:\/\/ionic.io\/blog\/ionic-react-and-realm#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/ionic.io\/blog\/ionic-react-and-realm"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/ionic.io\/blog\/ionic-react-and-realm#primaryimage","url":"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2021\/09\/realm-ionic-feature-image.png","contentUrl":"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2021\/09\/realm-ionic-feature-image.png","width":1600,"height":880},{"@type":"BreadcrumbList","@id":"https:\/\/ionic.io\/blog\/ionic-react-and-realm#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/ionic.io\/blog"},{"@type":"ListItem","position":2,"name":"Ionic React and Realm"}]},{"@type":"WebSite","@id":"https:\/\/ionic.io\/blog\/#website","url":"https:\/\/ionic.io\/blog\/","name":"ionic.io\/blog","description":"Build amazing native and progressive web apps with the web","publisher":{"@id":"https:\/\/ionic.io\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/ionic.io\/blog\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/ionic.io\/blog\/#organization","name":"Ionic","url":"https:\/\/ionic.io\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/ionic.io\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2020\/10\/white-on-color.png","contentUrl":"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2020\/10\/white-on-color.png","width":1920,"height":854,"caption":"Ionic"},"image":{"@id":"https:\/\/ionic.io\/blog\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/x.com\/ionicframework"]},{"@type":"Person","@id":"https:\/\/ionic.io\/blog\/#\/schema\/person\/c8c92b04d526adb925ea514c619a267b","name":"Mike Hartington","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/ionic.io\/blog\/#\/schema\/person\/image\/","url":"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2018\/08\/mike-headshot-2-smaller-150x150.png","contentUrl":"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2018\/08\/mike-headshot-2-smaller-150x150.png","caption":"Mike Hartington"},"description":"Director of Developer Relations","sameAs":["https:\/\/twitter.com\/mhartington","https:\/\/x.com\/mhartington"],"url":"https:\/\/ionic.io\/blog\/author\/mike"}]}},"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2021\/09\/realm-ionic-feature-image.png","_links":{"self":[{"href":"https:\/\/ionic.io\/blog\/wp-json\/wp\/v2\/posts\/3813","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ionic.io\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ionic.io\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ionic.io\/blog\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/ionic.io\/blog\/wp-json\/wp\/v2\/comments?post=3813"}],"version-history":[{"count":0,"href":"https:\/\/ionic.io\/blog\/wp-json\/wp\/v2\/posts\/3813\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/ionic.io\/blog\/wp-json\/wp\/v2\/media\/3817"}],"wp:attachment":[{"href":"https:\/\/ionic.io\/blog\/wp-json\/wp\/v2\/media?parent=3813"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ionic.io\/blog\/wp-json\/wp\/v2\/categories?post=3813"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ionic.io\/blog\/wp-json\/wp\/v2\/tags?post=3813"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}