If you need to persist data using
now, it’s recommended that you use a hosted database service. In this lesson we'll create a new, free MongoDB database on http://mlab.com and wire it up to use with our node.js app running on Zeit's
now hosting service.
[00:00] A lot of times when people start playing with now and getting excited about deploying their applications, there comes this crucial moment. They're like, "This is awesome. Where do I put my database?"
[00:13] That's actually a little bit tricky because this is all your now stuff gets served up on servers that are abstracted out from under you. You can't run a local MySQL database the way you might be doing if you were running your own, say, like a lamb stack.
[00:28] There's no mongo instance that's running concurrently with your server because you don't have access to the server. Right now, what the now team has been recommending to people is that they use a third party database, like just a hosted database solution.
[00:43] One way to do that is to use a company called mLab over here, mlab.com. They actually offer a free MongoDB database for 500 megs or less. This is great. We can play with this. I just created a new account. I'm going to create a new database. I'm going to make a single node database sandbox. This is free. This costs me nothing.
[01:10] My database name is going to be Egghead Now Lesson. My price per month is zero. I'm going to go ahead and create that. Now that's spinning up. The only thing we have to make sure we do is create a user. We're going to create a user. Username's going to be egghead. Password's going to be egghead.
[01:43] I'm going to delete this before I publish this so you can't steal my database. Then we're going to use MongoDB. There's a MongoDB driver we can install for Node. This is what we care about here, this connection string.
[01:59] Let's go to our application. Let's do mpm install, save, MongoDB. Then let's do touch database.js. Here's the functionality that we're going to add to our application. Every time somebody goes to the root URL here and gets the greeting and the timestamp, we're going to write that into the database.
[02:34] Then we're going to count up the total number of times that's happened and include that number in our result. Here's how we're going to do it. First, we're going to her to database.js. I've got over here some code pre-written that's going to make this work.
[02:54] Let's just step through it. We're going to import the Mongo client from MongoDB. Then we're going to read the Mongo user and Mongo password from our environment. The URL string then is going to be...This is going to be new based on the one I just created.
[03:10] Let's go here. Got to copy this and paste that in place. Then we just change this. Put username, this, to be password. You with me so far? This is all just bootstrap Mongo configuration. Then we're going to write a function which is going to be our primary interaction with the database.
[03:40] In this function, this is the way Mongo works if you've never used it, you're going to write these functions which perform operations on your behalf. They get the database injected into them as well as any arguments that you're going to take.
[03:52] In the database, we're going to look up or create the collection called "visits." Then we're going to insert an object. That object is just going to say here's the greeting that I used and here's the timestamp. The second argument it takes is a callback which checks to see if there was an error writing it and, if not, performs some other operations.
[04:16] Here we're just going to take the visits collection that we just mutated. We're going to count it and then that returns a promise. Then we call then, then that gets us our actual count. Then we call the callback that was passed in all the way at the top.
[04:31] It's a lot going on there. If you're not 100 percent up to speed on this, don't worry about it. The important things is we now have a function. Module.exports has a function called log request which takes a greeting, a timestamp, and a callback.
[04:48] Let's go over to our index.js. Let's say if our database equals require database. Now every time that comes in, first thing we need to do, let's abstract out our calls to get greeting and get date. Var greeting equals get greeting, var date equals get date, and then this'll just take the variable.
[05:16] What we want to do is say database.log request, we're going to give it the greeting, the date, and then a function. Going to stick this inside of our callback function here. The result of this callback function's actually going to be a count of the length of that visits collection, so let's call that "count."
[05:47] Let's make a quick update to our copy. That's going to say there have been count visits to this page. I think that should do it if I haven't typoed anything too egregiously. Let's go ahead and run it locally first. We're going to say...Got to make sure we get this environment variables named correctly.
[06:17] Mongo user equals egghead. Mongo pw equals egghead. What did we say? Greeting equals hi. Name equals egghead node index.js. Let's see if that all worked. Let's go here. Cool. We got our greeting in here, "Hi, egghead." You can see there have been two visits to this page.
[07:00] I'm going to refresh and now there's three, four, five, etc. This keeps going up. Great. We've got our database working locally. How do we use it remotely? This is actually super simple because remember we configured all of this to run using environment variables.
[07:24] All that means is that we need to go over here into package.json. When we deploy, we need to add two more arguments here. We've got greeting and we've got name. What we need now is -e Mongo user equals Mongo user and -e Mongo pw equals Mongo pw.
[07:49] We still have to create those two secrets. We say now secret add Mongo user egghead and now secret add Mongo pw egghead. Those secrets are in place. Let's go ahead and now secret add greeting. I think we already have this.
[08:31] Yes, now secret remove greeting. Just to change up our greetings now secret remove name, now secret add greeting hiya, and now secret add greeting friend. Oops, now secret add name friend. We've got our greeting. We've got our name. We've got our Mongo user. We've got our Mongo password.
[09:19] All that's left to do now is to run mpm run deploy. What did we do? There's no secret with the name Mongo password. Now secret add Mongo pw egghead. I must have typoed the secret name. Now we're deploying. We've got our URL. There we go.
[10:08] Now we're live on the Web. There have been six visits to this page because, remember, we're using a hosted database. This is not storing anything locally. This gets written out to the database that's hosted by mLab.
[10:20] If we go over here, we should be able to see collections. Let's refresh this page. There we go. We've got a collection called visits with six documents. You can see first five documents here all say, "Hi, egghead." The last one says, "Hiya, friend." The timestamps all vary.
[10:43] That should get you started. That's how you use a remote hosted database with a Node.js application running on now.
You could also use a docker container to spin up your app with any database you want, right?
No, absolutely not! You have no control over the instance(s) where your app runs. Other than a small temp folder you cannot assume persistence of any file system writes, which means your database can and will fragment when autoscaling!
@mykola Is there a way to use
.env? I believe on the zeit Slack I have seen the use of
dotenv by having something like
cp dev.env .env && now && rm .env
or something along those lines. Has that improved?
That's a great question, I'll see if I can dig something up. I believe your package.json file can define
now.env and have the keys -> values there be exported automagically, but obviously only do and commit this to your repo if you're using
now secrets via
@secretname as your values.
Hi there, your example is based on the mlab service. Would it be possible to do the same thing with Mongodb Atlas? Thanks