Postulate is the best way to take and share notes for classes, research, and other learning.
Create a new project and a new cluster in MongoDB Atlas. I select Azure as my cloud provider and name my cluster v1. I select the M0 free tier - it caps at 512 MB but that's no big deal because the entirety of Postulate is 13MB (as of last week).
Then, click "connect," allow access from anywhere with the 0.0.0.0/0
IP address, and select "from driver." I get a string that starts with mongodb+srv://
, and I add it as an environment variable, stored in a .env
file in the root directory of our project.
MongoDB tells you to replace myFirstDatabase in the URL with a database name, which confused me as no further explanation was provided and I was doing this for the first time. I'll spare you some head banging and here's the answer: basically, you can replace it with whatever you want your database to be named as. I name mine v1
.
Install mongoose in your Next.js project via npm i mongoose @types/mongoose
.
Create utils/dbConnnect.ts
- a utility function to reuse database connections. I got this code from the Postulate repository:
// from https://github.com/vercel/next.js/blob/canary/examples/with-mongodb-mongoose/utils/dbConnect.js
import mongoose from "mongoose";
const MONGODB_URL = process.env.MONGODB_URL // access environment variable
if (!MONGODB_URL) {
throw new Error(
'Please define the MONGODB_URL environment variable inside .env'
)
}
async function dbConnect() {
// check if we have a connection to the database or if it's currently
// connecting or disconnecting (readyState 1, 2 and 3)
if (mongoose.connection.readyState >= 1) {
return;
}
return mongoose.connect(MONGODB_URL, {
useNewUrlParser: true,
useUnifiedTopology: true,
useFindAndModify: false,
useCreateIndex: true,
maxIdleTimeMS: 10000,
socketTimeoutMS: 20000,
});
}
export default dbConnect;
Here's where the earlier environment variable comes in handy. We access it with process.env.MONGODB_URL
.
Following the tree that Samson laid out earlier in the PM spec, I create models. In models
folder, create Typescript files, each exporting one model. For example, here is models/account.ts
:
import mongoose, {Model, Document} from "mongoose";
import {AccountObj} from "../utils/types";
const AccountSchema = new mongoose.Schema({
email: {type: String, required: true},
name: {type: String, required: true},
image: {type: String, required: true},
trialExpDate: {type: String, required: true},
}, {
timestamps: true,
})
export const AccountModel: Model<Document<AccountObj>> = mongoose.models.account || mongoose.model("account", AccountSchema);
And here is the corresponding Typescript type in utils/types.ts
:
export interface AccountObj {
email: string,
name: string,
image: string,
trialExpDate: string // date string
}
With that, we have successfully set up our database!
Bonus: To verify that the configuration is correct, I can create an account from my Next app and store it in MongoDB after setting up NextAuth. To see our data, go to Clusters > v1 > Collections, and everything looks awesome 😁
Building a beta testing manager app with Laura