A Kinto Backend for the Vue Tutorial Search App

By |November 16th, 2017|Categories: JavaScript, Vue|Tags: , , |

A couple of months ago we started a Vue app that lists and searches for web development tutorials. It works nicely but was missing some key things. All of the data was hard-coded into the application and couldn’t be changed. Today we’ll be changing that.

For our backend, we first considered json-server, which makes it extremely simple to set up a REST server by giving it a JSON file with all of the data. We decided we wanted to test a different open source back end, though, and we settled on Kinto, which is developed by Mozilla. It offers offline-first functionality with its JavaScript client, a web-based admin, built-in synchronization, and real-time capabilities via Pusher (needs a plugin).

With Kinto handling our server-side storage and API, we’ll be updating the Tutorial Search application in a few ways:

  1. Instead of directly pulling tutorial data directly from data.js, Kinto will provide it to us.
  2. Vuex will directly use the Kinto API as well as provide the API for our components to consume.
  3. We will be able to add and delete tutorials from the list.

In order to save time, we will not be adding the ability to edit tutorials. Consider it a personal challenge for you to complete on your own before moving on to the next part of the tutorial.

Getting Started

Before we start plopping code into our editors we’ll need to do a bit of housecleaning. First, update all of your npm dependencies to the latest versions. My preferred way to accomplish this task is with npm-check. It shows you which packages are out-of-date, which version you have installed, and which version is latest. It then lets you select which packages to update. After you’ve done that, we need to install a few new dependencies:

That gives us Vuex and Kinto for the client side of the application, but we also need to get our backend set up. There are numerous ways to install Kinto onto a server, but the simplest for quick setup of prototyping apps would be to use one of the 3 buttons on their installation instruction page for deploying on cloud providers. For the sake of this tutorial, we used Heroku via the “Deploy to Heroku” button.

Once you’ve got it installed on a server, navigate to the admin interface at http(s?)://YOURDOMAIN/v1/admin/. If you’re using Heroku, it’ll be https://PROJECTNAME.herokuapp.com/v1/admin/. Here you can log in with whatever username and password you want since the BasicAuth authentication it comes with by default won’t put up any fight no matter what credentials you use. For this tutorial, everything will be public anyway, though we may get into securing things in the next article.

You should be on the main dashboard now, so click “Create Bucket”. Give the bucket an ID of “tut-search”. Within that bucket, click “Create Collection”. We’ll call this collection “tutorials” and you can use the following JSON schema:

And the following UI schema:

The rest of the settings can be as you see fit. I sorted by “-datePublished” and my columns were “title”, “url”, and “datePublished”. Once you’re done with that, click “Create collection.” Now you can enter all the tutorial records manually using the admin interface, but to save you some time, we’ll write a script to do it for us. Also, go to “Permissions” for the tutorials collection and make sure that an anonymous user can read, write, and create records.

Importing Data into Kinto

To import the data into Kinto quickly, we’ll work inside of main.js to write a little code that will import the data from data.js/ and use the Kinto API to put the records into our new Kinto database. First, we need to comment out all the code that is currently in main.js because we just want to run the import code. Then we’ll add this to the file:

Here we’re creating a Kinto collection connected to our backend. Then we iterate through our tutorials with reduce, waiting for the previous API call to finish and then telling Kinto to create a new tutorial. After all of them have been created, we need to sync so that it actually synchronizes with the backend, otherwise, this data will only be on the client. The final line is a debug line, so make sure your console is showing that ok is trueand that published has 22 elements. If there are any errors, you can look in the errors array for information on what went wrong. Make sure you edit the remote URL for your own application.

Use npm start to run the script in your browser and be sure to only run it once, otherwise, you’ll end up with duplicate records (you can always use the admin or API to delete the duplicates, but it’s just a bit of hassle you should try to avoid).

Now delete that code and uncomment the old code in main.js so we can move on to updating the actual application.

Creating a Vuex Store

We’ve got our tutorial data on the server now, so we need to start taking advantage of that. The first thing we need to do is remove the tutorial data from data.js, so it should only contain the technologies data:

For the sake of this tutorial, we won’t be putting this data onto the server. Now we need to start using Vuex, so create the store.js file in the src folder with the following contents:

This sets Vue up to use the Vuex plugin and creates a store with the tutorials module. We’ll create that module shortly, but first, we need to need to go into main.js and make the store available to all of the components:

Now let’s create that module for the Vuex store. Create a folder called stores and add the tutorials.js file to it:

The first few lines should look familiar since they’re quite similar to the ones we used in our import script. Once again, don’t forget to update the URL. The rest is setting up a namespaced store module. If this doesn’t make much sense to you, I recommend going through the excellent documentation for Vuex.

The store is designed in a way that you’ll always use the getters and actions, and the actions will use the mutations, but they shouldn’t be used by outside code. The actions all use the Kinto API to do the manipulations, sync them up to the server, and then update the Vuex store’s data with the synchronized data. In the import script, we saw create and sync, but here we’re also using delete, which will delete a record, and list, which will give us the data that is stored on the client so we can put it into the store for the getters to access.

Notice that the only error handling we have here is a simple console.error. You’ll probably want to do a lot more than that in a real user-facing application. This can be done by removing the catch here and letting the error propagate up to the calling components and they can handle the error cases.

A final note here: Kinto uses the fetch API, so if you need to support any browsers that don’t have it implemented, you’ll need to add a polyfill and this is the place to add it since this is the place where Kinto is used.

Updating the App to Use Vuex

Now we need to tell our app to use the data from Vuex, since it’s no longer available in data.js. To do that, open up components/App.vue and update the script portion to the following code.

The changes are noted in the comments so it should be simple to make the changes. Note that refactoring tutorials into the computed section wasn’t actually due to updating to use Vuex. It is simply a better way of writing the code that I didn’t think of when writing it for the first iteration of the application.

Now it should be displaying the tutorials from the backend as expected, but we have a problem: sometimes it can take a while to make that request for the tutorials, and while users are waiting for the tutorials to load, the app is telling them there are zero tutorials and doesn’t give any indication that we’re trying to download them. Let’s rectify this by creating a component that wraps around sections of our app and overlays them with a loading spinner during asynchronous operations.

To do this, we’ll create components/LoadingOverlay.vue and fill it with the following code:

The spinner is an adaptation of a CodePen example by Aurer (example 3). You can customize the text that is displayed beside the spinner and you control whether it is shown or not simply by passing in a Boolean to the isLoading prop.

Now let’s use this in components/App.vue to show the spinner while the app is starting up. First, wrap the Pagination and TutorialList section with the LoadingOverlay:

We’re using the listIsLoading property to signal when the overlay should show, so let’s edit the script part to import LoadingOverlay and control listIsLoading:

Now if you try running it again, you should see a loading overlay until the records show up. If it’s happening too quickly, you can use Chrome dev tools’ network throttling feature to slow things down.

Deleting Tutorials

Let’s add the ability to delete tutorials now. In components/Tutorial.vue, we’ll add a small overlay that appears when you hover over the tutorial and contains the delete button. This will make sure the delete button doesn’t clog the screen visually while you’re looking through the tutorials. We’ll also wrap the tutorial with LoadingOverlay because deleting a tutorial will be asynchronous again. Your file should look like this:

Adding New Tutorials

Of course, if all we can do is delete the tutorials, that means we’ll eventually run out of tutorials, so we need to be able to add some to the list as well. Let’s start by creating a form that can be used to create new tutorials. Add components/TutorialForm.vue with the following contents:

We’re emitting the submit event so the parent can handle the creation of a new tutorial in the store instead of adding that logic here. This allows it to be more generic and reusable. With a few tweaks like making the label of the button dynamic, we could make this truly generic so it could also be used for editing tutorials, but this will do for now.

You may have noticed the use of the FormInput component, which doesn’t exist yet. This is a helper component to remove some repetition and boilerplate for the forms. Let’s create that component now in components/FormInput.vue:

Sweet! Now there’s only one thing left to do: add this form to the app. Open up components/App.vue one more time and make the following edits:

And that’s everything! We’ve now updated our app to pull data from a Kinto back end, use Vuex as the store, and add/delete tutorials from the list! It was a quick and wild ride, but we made it and hopefully, we learned a little bit by the end of it.

Joe Zimmerman on Rss
Joe Zimmerman
Joseph Zimmerman (AKA Joe Zim) has been building web pages since he was 12. As he learned, he specialized in front-end JavaScript and has grown to be quite the expert. He blogs about what he knows on his own blog and several other blogs such as Smashing Magazine, Sitepoint, Tutsplus, and appendTo.