{"id":489,"date":"2015-11-11T15:00:00","date_gmt":"2015-11-11T15:00:00","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/cross-platform-storage-and-sync-with-ionic-framework-couchbase-and-pouchdb\/"},"modified":"2015-11-11T15:00:00","modified_gmt":"2015-11-11T15:00:00","slug":"cross-platform-storage-and-sync-with-ionic-framework-couchbase-and-pouchdb","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/ko\/cross-platform-storage-and-sync-with-ionic-framework-couchbase-and-pouchdb\/","title":{"rendered":"Cross Platform Storage and Sync with Ionic Framework, Couchbase, and PouchDB"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Ionic Framework is still one of the leaders in hybrid mobile application development. It allows you to create Android and iOS applications<br>\nusing only HTML, JavaScript, and CSS.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Previously I wrote about how to use <a href=\"https:\/\/www.couchbase.com\/blog\/using-couchbase-in-your-ionic-framework-application-part-1\/\">Couchbase in<br>\nan Ionic Framework mobile Android and iOS application<\/a>, but it made use of Couchbase<br>\nLite as its embedded NoSQL database. This time around we&#8217;re going to look at replacing Couchbase Lite with PouchDB. Should you use one<br>\nmethod over the other? No, it comes down to preference in the end.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If you haven&#8217;t already seen my post regarding <a href=\"https:\/\/www.couchbase.com\/blog\/sync-with-couchbase-using-only-angularjs-and-pouchdb\/\">PouchDB<br>\nand AngularJS with Couchbase<\/a>, I encourage you to have a look as this tutorial will be using many of the same concepts and code.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">What We&#8217;ll Need<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">There are a few requirements to the application we&#8217;re going to build. We&#8217;ll see how to obtain them along the way, but here is a<br>\ntaste so you know what you&#8217;re getting yourself into.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Couchbase Sync Gateway<\/li>\n\n\n<li>PouchDB 4<\/li>\n\n\n<li>Ionic Framework 1<\/li>\n\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Getting the Couchbase Sync Gateway<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">This project will require the Couchbase Sync Gateway in order to succeed. If you&#8217;re unfamiliar, the Couchbase Sync Gateway is a<br>\nmiddleman service that handles processing data between the local application (your Ionic Framework application) and the Couchbase Server. We<br>\nwon&#8217;t be using Couchbase Server in this example so the Sync Gateway will act as our in-memory storage solution in the cloud.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The Couchbase Sync Gateway can be found via the <a href=\"https:\/\/www.couchbase.com\/nosql-databases\/downloads\/\">Couchbase downloads section<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Creating Our Ionic Framework Project<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Before going any further it is good to note that if you&#8217;re not using a Mac, you cannot add and build for the iOS platform. Windows, Mac,<br>\nand Linux computers can build for Android, but only Mac can build for iOS.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">From the Command Prompt (Windows) or Terminal (Mac and Linux), execute the following command to create a new Ionic Framework project:<\/p>\n\n\n<p>[crayon lang=&#8221;bash&#8221;]<br \/>\nionic start PouchProject blank<br \/>\ncd PouchProject<br \/>\nionic platform add android<br \/>\nionic platform add ios<br \/>\n[\/crayon]<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Our blank template project is now ready for working with.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Including The Dependencies<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">If you haven&#8217;t already, <a href=\"https:\/\/www.pouchdb.com\/\">download PouchDB 4<\/a> and make note of the <strong>min.js<\/strong> file as<br>\nwe&#8217;ll be using it through the project. Copy the<br>\nPouchDB <strong>min.js<\/strong> file into your Ionic project&#8217;s <strong>www\/js<\/strong> directory.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">With the file in place, open your project&#8217;s <strong>www\/index.html<\/strong> file and include the following:<\/p>\n\n\n<p>[crayon lang=&#8221;html&#8221;]<\/p>\n<p>[\/crayon]<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This script line should appear above the <strong>app.js<\/strong> include line and the version information should match that of your actual<br>\nfile rather than the version I included here.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Modifying The Index File<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Before we jump into the AngularJS code we need to make a final revision to the project&#8217;s <strong>www\/index.html<\/strong> file. Open it and<br>\nreplace the tags with the following:<\/p>\n\n\n<p>[crayon lang=&#8221;html&#8221;]<\/p>\n<p>[\/crayon]<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Because we&#8217;re using the AngularJS UI-Router that ships with Ionic Framework, we only need a basic <strong>www\/index.html<\/strong> file.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Creating Our PouchDB AngularJS Service<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Before we start using PouchDB, we need to make a wrapper for it so it fits nicely with AngularJS and Ionic Framework. Out of the box PouchDB<br>\nis a vanilla JavaScript library, so it isn&#8217;t necessarily the easiest to use when it comes to AngularJS.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Inside your project&#8217;s <strong>www\/js\/app.js<\/strong> file, include the following service code:<\/p>\n\n\n<p>[crayon lang=&#8221;javascript&#8221;]<br \/>\n.service(&#8220;$pouchDB&#8221;, [&#8220;$rootScope&#8221;, &#8220;$q&#8221;, function($rootScope, $q) {<\/p>\n<p>    var database;<br \/>\n    var changeListener;<\/p>\n<p>    this.setDatabase = function(databaseName) {<br \/>\n        database = new PouchDB(databaseName);<br \/>\n    }<\/p>\n<p>    this.startListening = function() {<br \/>\n        changeListener = database.changes({<br \/>\n            live: true,<br \/>\n            include_docs: true<br \/>\n        }).on(&#8220;change&#8221;, function(change) {<br \/>\n            if(!change.deleted) {<br \/>\n                $rootScope.$broadcast(&#8220;$pouchDB:change&#8221;, change);<br \/>\n            } else {<br \/>\n                $rootScope.$broadcast(&#8220;$pouchDB:delete&#8221;, change);<br \/>\n            }<br \/>\n        });<br \/>\n    }<\/p>\n<p>    this.stopListening = function() {<br \/>\n        changeListener.cancel();<br \/>\n    }<\/p>\n<p>    this.sync = function(remoteDatabase) {<br \/>\n        database.sync(remoteDatabase, {live: true, retry: true});<br \/>\n    }<\/p>\n<p>    this.save = function(jsonDocument) {<br \/>\n        var deferred = $q.defer();<br \/>\n        if(!jsonDocument._id) {<br \/>\n            database.post(jsonDocument).then(function(response) {<br \/>\n                deferred.resolve(response);<br \/>\n            }).catch(function(error) {<br \/>\n                deferred.reject(error);<br \/>\n            });<br \/>\n        } else {<br \/>\n            database.put(jsonDocument).then(function(response) {<br \/>\n                deferred.resolve(response);<br \/>\n            }).catch(function(error) {<br \/>\n                deferred.reject(error);<br \/>\n            });<br \/>\n        }<br \/>\n        return deferred.promise;<br \/>\n    }<\/p>\n<p>    this.delete = function(documentId, documentRevision) {<br \/>\n        return database.remove(documentId, documentRevision);<br \/>\n    }<\/p>\n<p>    this.get = function(documentId) {<br \/>\n        return database.get(documentId);<br \/>\n    }<\/p>\n<p>    this.destroy = function() {<br \/>\n        database.destroy();<br \/>\n    }<\/p>\n<p>}])<br \/>\n[\/crayon]<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You might be thinking that code looks familiar. Well, it is the exact code I used in<br>\nthe <a href=\"https:\/\/www.couchbase.com\/blog\/sync-with-couchbase-using-only-angularjs-and-pouchdb\/\">previous PouchDB example for AngularJS<\/a>.<br>\nNow we can easily use PouchDB in our project.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Creating A Local Database And Start Syncing<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The goal here is to create a local database when our application starts (if it doesn&#8217;t already exist) and then start syncing with the<br>\nCouchbase Sync Gateway. This can be accomplished in the AngularJS <strong>run()<\/strong> function of our <strong>www\/js\/app.js<\/strong><br>\nfile:<\/p>\n\n\n<p>[crayon lang=&#8221;javascript&#8221;]<br \/>\n.run(function($ionicPlatform, $pouchDB) {<br \/>\n    $ionicPlatform.ready(function() {<br \/>\n        if(window.cordova &#038;&#038; window.cordova.plugins.Keyboard) {<br \/>\n            cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);<br \/>\n        }<br \/>\n        if(window.StatusBar) {<br \/>\n            StatusBar.styleDefault();<br \/>\n        }<br \/>\n    });<br \/>\n    $pouchDB.setDatabase(&#8220;nraboy-test&#8221;);<br \/>\n    if(ionic.Platform.isAndroid()) {<br \/>\n        $pouchDB.sync(&#8220;https:\/\/192.168.57.1:4984\/test-database&#8221;);<br \/>\n    } else {<br \/>\n        $pouchDB.sync(&#8220;https:\/\/localhost:4984\/test-database&#8221;);<br \/>\n    }<br \/>\n})<br \/>\n[\/crayon]<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The IP addresses I used might vary for you in terms of simulators, but for production they will likely match for both iOS and<br>\nAndroid.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Designing A Controller For Your Views<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">We haven&#8217;t created our views yet, but let&#8217;s go ahead and create the controller logic for them. Open your project&#8217;s<br>\n<strong>www\/js\/app.js<\/strong> file and include the following controller:<\/p>\n\n\n<p>[crayon lang=&#8221;javascript&#8221;]<br \/>\n.controller(&#8220;MainController&#8221;, function($scope, $rootScope, $state, $stateParams, $ionicHistory, $pouchDB) {<\/p>\n<p>    $scope.items = {};<\/p>\n<p>    $scope.save = function(firstname, lastname, email) { }<\/p>\n<p>    $scope.delete = function(id, rev) { }<\/p>\n<p>    $scope.back = function() { }<\/p>\n<p>})<br \/>\n[\/crayon]<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">As of right now we have a basic controller. We know we&#8217;ll be saving and deleting items which is why we&#8217;ve defined a function for such<br>\ntasks. We also have a function called <strong>back()<\/strong> that will pop an item (go back) in the history stack.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Let&#8217;s go bottom up and start with the <strong>back()<\/strong> function. It should contain the following code:<\/p>\n\n\n<p>[crayon lang=&#8221;javascript&#8221;]<br \/>\n$scope.back = function() {<br \/>\n    $ionicHistory.goBack();<br \/>\n}<br \/>\n[\/crayon]<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">When it comes to deleting items from the database we&#8217;ll need to provide a particular document id to delete as well as the particular revision<br>\nwe wish to delete. This will all be passed from the views, but the logic will be as follows:<\/p>\n\n\n<p>[crayon lang=&#8221;javascript&#8221;]<br \/>\n$scope.delete = function(id, rev) {<br \/>\n    $pouchDB.delete(id, rev);<br \/>\n}<br \/>\n[\/crayon]<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The <strong>delete(id, rev)<\/strong> function makes a call to the PouchDB service that we made.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This leaves us with the <strong>save()<\/strong> function. Based on the simplicity of our application we&#8217;ll only be saving three data<br>\nproperties, but it can easily be changed should you need to. Inside your controller, make the <strong>save()<\/strong> function like so:<\/p>\n\n\n<p>[crayon lang=&#8221;javascript&#8221;]<br \/>\n$scope.save = function(firstname, lastname, email) {<br \/>\n    var jsonDocument = {<br \/>\n        &#8220;firstname&#8221;: firstname,<br \/>\n        &#8220;lastname&#8221;: lastname,<br \/>\n        &#8220;email&#8221;: email<br \/>\n    };<br \/>\n    if($stateParams.documentId) {<br \/>\n        jsonDocument[&#8220;_id&#8221;] = $stateParams.documentId;<br \/>\n        jsonDocument[&#8220;_rev&#8221;] = $stateParams.documentRevision;<br \/>\n    }<br \/>\n    $pouchDB.save(jsonDocument).then(function(response) {<br \/>\n        $state.go(&#8220;list&#8221;);<br \/>\n    }, function(error) {<br \/>\n        console.log(&#8220;ERROR -> &#8221; + error);<br \/>\n    });<br \/>\n}<br \/>\n[\/crayon]<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This function does two things. It will prepare an insert or it will prepare an update should a document id and document revision<br>\nbe available.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We&#8217;re not quite done yet though. Although we finished all our functions, we still need to handle listening for<br>\nchanges. When we call <strong>$pouchDB.startListening();<\/strong> in our controller, our PouchDB service will start making use of the<br>\nAngularJS <strong>$broadcast<\/strong>. While it is broadcasting we can listen for those broadcasts using something like:<\/p>\n\n\n<p>[crayon lang=&#8221;javascript&#8221;]<br \/>\n$rootScope.$on(&#8220;$pouchDB:change&#8221;, function(event, data) {<br \/>\n    $scope.items[data.doc._id] = data.doc;<br \/>\n    $scope.$apply();<br \/>\n});<\/p>\n<p>$rootScope.$on(&#8220;$pouchDB:delete&#8221;, function(event, data) {<br \/>\n    delete $scope.items[data.doc._id];<br \/>\n    $scope.$apply();<br \/>\n});<br \/>\n[\/crayon]<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Our view controller logic is now good to go!<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Defining Your Ionic Framework Views<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The last part of our <strong>www\/js\/app.js<\/strong> file will be for defining our views. This is done in the AngularJS<br>\n<strong>config()<\/strong> function like so:<\/p>\n\n\n<p>[crayon lang=&#8221;javascript&#8221;]<br \/>\n.config(function($stateProvider, $urlRouterProvider) {<br \/>\n    $stateProvider<br \/>\n        .state(&#8220;list&#8221;, {<br \/>\n            &#8220;url&#8221;: &#8220;\/list&#8221;,<br \/>\n            &#8220;templateUrl&#8221;: &#8220;templates\/list.html&#8221;,<br \/>\n            &#8220;controller&#8221;: &#8220;MainController&#8221;<br \/>\n        })<br \/>\n        .state(&#8220;item&#8221;, {<br \/>\n            &#8220;url&#8221;: &#8220;\/item\/:documentId\/:documentRevision&#8221;,<br \/>\n            &#8220;templateUrl&#8221;: &#8220;templates\/item.html&#8221;,<br \/>\n            &#8220;controller&#8221;: &#8220;MainController&#8221;<br \/>\n        });<br \/>\n    $urlRouterProvider.otherwise(&#8220;list&#8221;);<br \/>\n})<br \/>\n[\/crayon]<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We defined two views, one for all our list items and one for creating and updating new list items. The <strong>item<\/strong> state takes an optional<br>\ndocument id and document revision parameter. When they are present, it means we are going to be updating a particular document.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">All our AngularJS logic is complete now. We have initialized our database, started syncing, defined our views, and planned for interaction<br>\nfrom our views.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Creating A List View<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Here we will define how data is presented in the list. In your project&#8217;s <strong>www\/templates\/list.html<\/strong> file, add the following code:<\/p>\n\n\n<p>[crayon lang=&#8221;html&#8221;]<\/p>\n<p>                {{value.firstname}} {{value.lastname}}<\/p>\n<p>[\/crayon]<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">When swiping a list item we are presented with a delete button that will call the <strong>delete()<\/strong> function of our controller.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Creating A Form View<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Here we will define out documents will be inserted or updated in our database. Essentially, this view is only a form. In your project&#8217;s<br>\n<strong>www\/templates\/item.html<\/strong> file, add the following code:<\/p>\n\n\n\n<label class=\"item item-input\">  <\/label>\n\n\n\n<label class=\"item item-input\">  <\/label>\n\n\n\n<label class=\"item item-input\">  <\/label>\n\n\n\n<p class=\"wp-block-paragraph\">\u00a0<\/p>\n\n\n\n<button class=\"button button-block button-positive\"> Save <\/button>\n\n\n\n<h2 class=\"wp-block-heading\">The Sync Gateway Configuration<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">PouchDB and Ionic Framework are only half the story here. Sure they will create a nice locally running application, but we want things to sync. The Couchbase Sync Gateway is our endpoint for this and of course PouchDB works great with it.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Inside your project&#8217;s <strong>sync-gateway-config.json<\/strong> file, add the following:<\/p>\n\n\n<p>[crayon lang=&#8221;json&#8221;]<br \/>\n{<br \/>\n    &#8220;log&#8221;:[&#8220;CRUD+&#8221;, &#8220;REST+&#8221;, &#8220;Changes+&#8221;, &#8220;Attach+&#8221;],<br \/>\n    &#8220;databases&#8221;: {<br \/>\n        &#8220;test-database&#8221;: {<br \/>\n            &#8220;server&#8221;:&#8221;walrus:data&#8221;,<br \/>\n            &#8220;sync&#8221;:`<br \/>\n                function (doc) {<br \/>\n                    channel (doc.channels);<br \/>\n                }<br \/>\n            `,<br \/>\n            &#8220;users&#8221;: {<br \/>\n                &#8220;GUEST&#8221;: {<br \/>\n                    &#8220;disabled&#8221;: false,<br \/>\n                    &#8220;admin_channels&#8221;: [&#8220;*&#8221;]<br \/>\n                }<br \/>\n            }<br \/>\n        }<br \/>\n    },<br \/>\n    &#8220;CORS&#8221;: {<br \/>\n        &#8220;Origin&#8221;: [&#8220;https:\/\/localhost:9000&#8221;],<br \/>\n        &#8220;LoginOrigin&#8221;: [&#8220;https:\/\/localhost:9000&#8221;],<br \/>\n        &#8220;Headers&#8221;: [&#8220;Content-Type&#8221;],<br \/>\n        &#8220;MaxAge&#8221;: 17280000<br \/>\n    }<br \/>\n}<br \/>\n[\/crayon]<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This is one of the most basic configurations around. A few things to note about it:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>It uses walrus:data for storage which is in memory and does not persist. Not to be used for production.<\/li>\n\n\n<li>All data is synced via the GUEST user, so there is no authentication happening here, but there could be.<\/li>\n\n\n<li>We are fixing CORS issues by allowing requests on localhost:9000 in case you wanted to serve with Python for browser testing.<\/li>\n\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Testing The Application<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">At this point all our code is in place and our Sync Gateway is ready to be run. Start up the Sync Gateway by running the following in a<br>\nCommand Prompt or Terminal:<\/p>\n\n\n<p>[crayon lang=&#8221;bash&#8221;]<br \/>\n\/path\/to\/sync\/gateway\/bin\/sync-gateway \/path\/to\/project\/sync-gateway-config.json<br \/>\n[\/crayon]<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The Sync Gateway should now be running and you can validate this by visiting https:\/\/localhost:4984 in your web browser.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Testing For Android<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">With a device connected or a simulator running, from the Command Prompt or Terminal, run the following two commands to build and<br>\ninstall the APK file:<\/p>\n\n\n<p>[crayon lang=&#8221;bash&#8221;]<br \/>\nionic build android<br \/>\nadb install -r platforms\/android\/build\/outputs\/apk\/android-debug.apk<br \/>\n[\/crayon]<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Testing For iOS<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">There are two good ways to do this. You can either build the project and open it with Xcode, or you can build and<br>\nemulate the application without launching Xcode. The first can be done like so:<\/p>\n\n\n<p>[crayon lang=&#8221;bash&#8221;]<br \/>\nionic build ios<br \/>\n[\/crayon]<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Then open the project&#8217;s platform\/ios\/ directory and launch the Xcode project file.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If you&#8217;ve installed the Node Package Manager (NPM) package ios-sim, you can do the following:<\/p>\n\n\n<p>[crayon lang=&#8221;bash&#8221;]<br \/>\nionic build ios<br \/>\nionic emulate ios<br \/>\n[\/crayon]<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">You saw now that there are two ways you can use Couchbase in your Ionic Framework mobile Android and iOS application. You can use the<br>\nApache Cordova Couchbase plugin as demonstrated in<br>\nthe <a href=\"https:\/\/www.couchbase.com\/blog\/using-couchbase-in-your-ionic-framework-application-part-1\/\">previous blog series<\/a>, or you can<br>\nuse PouchDB. Both of these are very suitable options when it comes to cross platform data storage and sync in your application.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You can obtain the full working source code to this blog post via<br>\nour <a href=\"https:\/\/github.com\/couchbaselabs\/ionic-framework-pouchdb\">Couchbase Labs GitHub repository<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Ionic Framework is still one of the leaders in hybrid mobile application development. It allows you to create Android and iOS applications using only HTML, JavaScript, and CSS. Previously I wrote about how to use Couchbase in an Ionic Framework mobile Android and iOS application, but it made use of Couchbase Lite as its embedded [&hellip;]<\/p>\n","protected":false},"author":63,"featured_media":18,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"_acf":"","footnotes":""},"categories":[1],"tags":[164,168,161,166],"ppma_author":[148],"class_list":["post-489","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","tag-angularjs","tag-hybrid","tag-ionic-framework","tag-pouchdb"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v27.6 (Yoast SEO v27.6) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Sync Couchbase in Ionic Framework and PouchDB<\/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\/ko\/cross-platform-storage-and-sync-with-ionic-framework-couchbase-and-pouchdb\/\" \/>\n<meta property=\"og:locale\" content=\"ko_KR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Cross Platform Storage and Sync with Ionic Framework, Couchbase, and PouchDB\" \/>\n<meta property=\"og:description\" content=\"Ionic Framework is still one of the leaders in hybrid mobile application development. It allows you to create Android and iOS applications using only HTML, JavaScript, and CSS. Previously I wrote about how to use Couchbase in an Ionic Framework mobile Android and iOS application, but it made use of Couchbase Lite as its embedded [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/ko\/cross-platform-storage-and-sync-with-ionic-framework-couchbase-and-pouchdb\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/thepolyglotdeveloper\" \/>\n<meta property=\"article:published_time\" content=\"2015-11-11T15:00:00+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/5\/2026\/05\/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=\"Nic Raboy, Developer Advocate, Couchbase\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@nraboy\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Nic Raboy, Developer Advocate, Couchbase\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"8\ubd84\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/cross-platform-storage-and-sync-with-ionic-framework-couchbase-and-pouchdb\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/cross-platform-storage-and-sync-with-ionic-framework-couchbase-and-pouchdb\\\/\"},\"author\":{\"name\":\"Nic Raboy, Developer Advocate, Couchbase\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#\\\/schema\\\/person\\\/bb545ebe83bb2d12f91095811d0a72e1\"},\"headline\":\"Cross Platform Storage and Sync with Ionic Framework, Couchbase, and PouchDB\",\"datePublished\":\"2015-11-11T15:00:00+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/cross-platform-storage-and-sync-with-ionic-framework-couchbase-and-pouchdb\\\/\"},\"wordCount\":1967,\"commentCount\":28,\"publisher\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/cross-platform-storage-and-sync-with-ionic-framework-couchbase-and-pouchdb\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/5\\\/2026\\\/05\\\/couchbase-nosql-dbaas.png\",\"keywords\":[\"angularjs\",\"hybrid\",\"ionic framework\",\"pouchdb\"],\"articleSection\":[\"Uncategorized\"],\"inLanguage\":\"ko-KR\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/cross-platform-storage-and-sync-with-ionic-framework-couchbase-and-pouchdb\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/cross-platform-storage-and-sync-with-ionic-framework-couchbase-and-pouchdb\\\/\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/cross-platform-storage-and-sync-with-ionic-framework-couchbase-and-pouchdb\\\/\",\"name\":\"Sync Couchbase in Ionic Framework and PouchDB\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/cross-platform-storage-and-sync-with-ionic-framework-couchbase-and-pouchdb\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/cross-platform-storage-and-sync-with-ionic-framework-couchbase-and-pouchdb\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/5\\\/2026\\\/05\\\/couchbase-nosql-dbaas.png\",\"datePublished\":\"2015-11-11T15:00:00+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/cross-platform-storage-and-sync-with-ionic-framework-couchbase-and-pouchdb\\\/#breadcrumb\"},\"inLanguage\":\"ko-KR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/cross-platform-storage-and-sync-with-ionic-framework-couchbase-and-pouchdb\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"ko-KR\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/cross-platform-storage-and-sync-with-ionic-framework-couchbase-and-pouchdb\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/5\\\/2026\\\/05\\\/couchbase-nosql-dbaas.png\",\"contentUrl\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/5\\\/2026\\\/05\\\/couchbase-nosql-dbaas.png\",\"width\":1800,\"height\":630},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/cross-platform-storage-and-sync-with-ionic-framework-couchbase-and-pouchdb\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Cross Platform Storage and Sync with Ionic Framework, Couchbase, and PouchDB\"}]},{\"@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\":\"ko-KR\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#organization\",\"name\":\"The Couchbase Blog\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"ko-KR\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/5\\\/2026\\\/06\\\/logo.svg\",\"contentUrl\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/5\\\/2026\\\/06\\\/logo.svg\",\"width\":\"1024\",\"height\":\"1024\",\"caption\":\"The Couchbase Blog\"},\"image\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#\\\/schema\\\/person\\\/bb545ebe83bb2d12f91095811d0a72e1\",\"name\":\"Nic Raboy, Developer Advocate, Couchbase\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"ko-KR\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/bedeb68368d4681aca4c74fe5f697f0c423b80d498ec50fd915ba018b72c101f?s=96&d=mm&r=g8863514d8bed0cf6080f23db40e00354\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/bedeb68368d4681aca4c74fe5f697f0c423b80d498ec50fd915ba018b72c101f?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/bedeb68368d4681aca4c74fe5f697f0c423b80d498ec50fd915ba018b72c101f?s=96&d=mm&r=g\",\"caption\":\"Nic Raboy, Developer Advocate, Couchbase\"},\"description\":\"Nic Raboy is an advocate of modern web and mobile development technologies. He has experience in Java, JavaScript, Golang and a variety of frameworks such as Angular, NativeScript, and Apache Cordova. Nic writes about his development experiences related to making web and mobile development easier to understand.\",\"sameAs\":[\"https:\\\/\\\/www.thepolyglotdeveloper.com\",\"https:\\\/\\\/www.facebook.com\\\/thepolyglotdeveloper\",\"https:\\\/\\\/x.com\\\/nraboy\"],\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/ko\\\/author\\\/nic-raboy-2\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Sync Couchbase in Ionic Framework and PouchDB","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\/ko\/cross-platform-storage-and-sync-with-ionic-framework-couchbase-and-pouchdb\/","og_locale":"ko_KR","og_type":"article","og_title":"Cross Platform Storage and Sync with Ionic Framework, Couchbase, and PouchDB","og_description":"Ionic Framework is still one of the leaders in hybrid mobile application development. It allows you to create Android and iOS applications using only HTML, JavaScript, and CSS. Previously I wrote about how to use Couchbase in an Ionic Framework mobile Android and iOS application, but it made use of Couchbase Lite as its embedded [&hellip;]","og_url":"https:\/\/www.couchbase.com\/blog\/ko\/cross-platform-storage-and-sync-with-ionic-framework-couchbase-and-pouchdb\/","og_site_name":"The Couchbase Blog","article_author":"https:\/\/www.facebook.com\/thepolyglotdeveloper","article_published_time":"2015-11-11T15:00:00+00:00","og_image":[{"width":1800,"height":630,"url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/5\/2026\/05\/couchbase-nosql-dbaas.png","type":"image\/png"}],"author":"Nic Raboy, Developer Advocate, Couchbase","twitter_card":"summary_large_image","twitter_creator":"@nraboy","twitter_misc":{"Written by":"Nic Raboy, Developer Advocate, Couchbase","Est. reading time":"8\ubd84"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/cross-platform-storage-and-sync-with-ionic-framework-couchbase-and-pouchdb\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/cross-platform-storage-and-sync-with-ionic-framework-couchbase-and-pouchdb\/"},"author":{"name":"Nic Raboy, Developer Advocate, Couchbase","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/bb545ebe83bb2d12f91095811d0a72e1"},"headline":"Cross Platform Storage and Sync with Ionic Framework, Couchbase, and PouchDB","datePublished":"2015-11-11T15:00:00+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/cross-platform-storage-and-sync-with-ionic-framework-couchbase-and-pouchdb\/"},"wordCount":1967,"commentCount":28,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/cross-platform-storage-and-sync-with-ionic-framework-couchbase-and-pouchdb\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/5\/2026\/05\/couchbase-nosql-dbaas.png","keywords":["angularjs","hybrid","ionic framework","pouchdb"],"articleSection":["Uncategorized"],"inLanguage":"ko-KR","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/cross-platform-storage-and-sync-with-ionic-framework-couchbase-and-pouchdb\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/cross-platform-storage-and-sync-with-ionic-framework-couchbase-and-pouchdb\/","url":"https:\/\/www.couchbase.com\/blog\/cross-platform-storage-and-sync-with-ionic-framework-couchbase-and-pouchdb\/","name":"Sync Couchbase in Ionic Framework and PouchDB","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/cross-platform-storage-and-sync-with-ionic-framework-couchbase-and-pouchdb\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/cross-platform-storage-and-sync-with-ionic-framework-couchbase-and-pouchdb\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/5\/2026\/05\/couchbase-nosql-dbaas.png","datePublished":"2015-11-11T15:00:00+00:00","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/cross-platform-storage-and-sync-with-ionic-framework-couchbase-and-pouchdb\/#breadcrumb"},"inLanguage":"ko-KR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/cross-platform-storage-and-sync-with-ionic-framework-couchbase-and-pouchdb\/"]}]},{"@type":"ImageObject","inLanguage":"ko-KR","@id":"https:\/\/www.couchbase.com\/blog\/cross-platform-storage-and-sync-with-ionic-framework-couchbase-and-pouchdb\/#primaryimage","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/5\/2026\/05\/couchbase-nosql-dbaas.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/5\/2026\/05\/couchbase-nosql-dbaas.png","width":1800,"height":630},{"@type":"BreadcrumbList","@id":"https:\/\/www.couchbase.com\/blog\/cross-platform-storage-and-sync-with-ionic-framework-couchbase-and-pouchdb\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Cross Platform Storage and Sync with Ionic Framework, Couchbase, and PouchDB"}]},{"@type":"WebSite","@id":"https:\/\/www.couchbase.com\/blog\/#website","url":"https:\/\/www.couchbase.com\/blog\/","name":"\uce74\uc6b0\uce58\ubca0\uc774\uc2a4 \ube14\ub85c\uadf8","description":"\uce74\uc6b0\uce58\ubca0\uc774\uc2a4, NoSQL \ub370\uc774\ud130\ubca0\uc774\uc2a4","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":"ko-KR"},{"@type":"Organization","@id":"https:\/\/www.couchbase.com\/blog\/#organization","name":"\uce74\uc6b0\uce58\ubca0\uc774\uc2a4 \ube14\ub85c\uadf8","url":"https:\/\/www.couchbase.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"ko-KR","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/5\/2026\/06\/logo.svg","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/5\/2026\/06\/logo.svg","width":"1024","height":"1024","caption":"The Couchbase Blog"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/bb545ebe83bb2d12f91095811d0a72e1","name":"\ub2c9 \ub77c\ubcf4\uc774, \uac1c\ubc1c\uc790 \uc560\ub4dc\ubcf4\ucf00\uc774\ud2b8, \uce74\uc6b0\uce58\ubca0\uc774\uc2a4","image":{"@type":"ImageObject","inLanguage":"ko-KR","@id":"https:\/\/secure.gravatar.com\/avatar\/bedeb68368d4681aca4c74fe5f697f0c423b80d498ec50fd915ba018b72c101f?s=96&d=mm&r=g8863514d8bed0cf6080f23db40e00354","url":"https:\/\/secure.gravatar.com\/avatar\/bedeb68368d4681aca4c74fe5f697f0c423b80d498ec50fd915ba018b72c101f?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/bedeb68368d4681aca4c74fe5f697f0c423b80d498ec50fd915ba018b72c101f?s=96&d=mm&r=g","caption":"Nic Raboy, Developer Advocate, Couchbase"},"description":"\ub2c9 \ub77c\ubcf4\uc774(Nic Raboy)\ub294 \ubaa8\ub358 \uc6f9 \ubc0f \ubaa8\ubc14\uc77c \uac1c\ubc1c \uae30\uc220\uc758 \uc639\ud638\uc790\uc785\ub2c8\ub2e4. \uadf8\ub294 \uc790\ubc14, \uc790\ubc14\uc2a4\ud06c\ub9bd\ud2b8, \uace8\ub791(Golang)\uc744 \ube44\ub86f\ud574 \uc575\uade4\ub7ec, \ub124\uc774\ud2f0\ube0c\uc2a4\ud06c\ub9bd\ud2b8, \uc544\ud30c\uce58 \ucf54\ub974\ub3c4\ubc14 \uac19\uc740 \ub2e4\uc591\ud55c \ud504\ub808\uc784\uc6cc\ud06c \uacbd\ud5d8\uc744 \uac00\uc9c0\uace0 \uc788\uc2b5\ub2c8\ub2e4. \ub2c9\uc740 \uc6f9 \ubc0f \ubaa8\ubc14\uc77c \uac1c\ubc1c\uc744 \ub354 \uc27d\uac8c \uc774\ud574\ud560 \uc218 \uc788\ub3c4\ub85d \ub3d5\ub294 \uc790\uc2e0\uc758 \uac1c\ubc1c \uacbd\ud5d8\uc5d0 \ub300\ud574 \uae00\uc744 \uc501\ub2c8\ub2e4.","sameAs":["https:\/\/www.thepolyglotdeveloper.com","https:\/\/www.facebook.com\/thepolyglotdeveloper","https:\/\/x.com\/nraboy"],"url":"https:\/\/www.couchbase.com\/blog\/ko\/author\/nic-raboy-2\/"}]}},"acf":[],"authors":[{"term_id":148,"user_id":63,"is_guest":0,"slug":"nic-raboy-2","display_name":"Nic Raboy, Developer Advocate, Couchbase","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/?s=96&d=mm&r=g","author_category":"","first_name":"Nic","last_name":"Raboy","user_url":"","job_title":"","description":"\ub2c9 \ub77c\ubcf4\uc774(Nic Raboy)\ub294 \ubaa8\ub358 \uc6f9 \ubc0f \ubaa8\ubc14\uc77c \uac1c\ubc1c \uae30\uc220\uc758 \uc639\ud638\uc790\uc785\ub2c8\ub2e4. \uadf8\ub294 \uc790\ubc14, \uc790\ubc14\uc2a4\ud06c\ub9bd\ud2b8, \uace8\ub791(Golang)\uc744 \ube44\ub86f\ud574 \uc575\uade4\ub7ec, \ub124\uc774\ud2f0\ube0c\uc2a4\ud06c\ub9bd\ud2b8, \uc544\ud30c\uce58 \ucf54\ub974\ub3c4\ubc14 \uac19\uc740 \ub2e4\uc591\ud55c \ud504\ub808\uc784\uc6cc\ud06c \uacbd\ud5d8\uc744 \uac00\uc9c0\uace0 \uc788\uc2b5\ub2c8\ub2e4. \ub2c9\uc740 \uc6f9 \ubc0f \ubaa8\ubc14\uc77c \uac1c\ubc1c\uc744 \ub354 \uc27d\uac8c \uc774\ud574\ud560 \uc218 \uc788\ub3c4\ub85d \ub3d5\ub294 \uc790\uc2e0\uc758 \uac1c\ubc1c \uacbd\ud5d8\uc5d0 \ub300\ud574 \uae00\uc744 \uc501\ub2c8\ub2e4."}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/ko\/wp-json\/wp\/v2\/posts\/489","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.couchbase.com\/blog\/ko\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.couchbase.com\/blog\/ko\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/ko\/wp-json\/wp\/v2\/users\/63"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/ko\/wp-json\/wp\/v2\/comments?post=489"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/ko\/wp-json\/wp\/v2\/posts\/489\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/ko\/wp-json\/wp\/v2\/media\/18"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/ko\/wp-json\/wp\/v2\/media?parent=489"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/ko\/wp-json\/wp\/v2\/categories?post=489"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/ko\/wp-json\/wp\/v2\/tags?post=489"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/ko\/wp-json\/wp\/v2\/ppma_author?post=489"}],"curies":[{"name":"\uc798\ud588\uc5b4","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}