2024: Domino Containers - The Next Step. News from the Domino Container commu...
MongoDB World 2018: Tutorial - Got Dibs? Building a Real-Time Bidding App with Change Streams
1. While you wait…
...let’s get some things out of the way
• Install MongoDB 3.6 or 4.0
• https://docs.mongodb.com/manual/installation/#mongodb-community-edition
• Install Node 8 or Node 10
• https://nodejs.org/en/
• Download the code we’ll start with, and unzip it
• https://github.com/hswolff/dibs/archive/tutorial-start.zip
• Install all dependencies
• cd client && npm install && cd ../server && npm install
2. Got Dibs? Building a
Real-Time Bidding App
with Change Streams
A tutorial by Harry Wolff
18. Outline
1. Prerequisites
2. Create the Server
a. Set up MongoDB
b. Create server folder
c. Connect to MongoDB
d. Set up our API
e. Create API endpoints
3. Create the Client
a. Create client folder
b. Connect to our API
c. Render all dibs
d. Add support for creating a dib
e. Enable a user to log in
4. Let's call dibs
a. Server support
b. Client support
5. To real time, and beyond!
a. Server support
b. Client support
19. Outline
1. Prerequisites
2. Create the Server
a. Set up MongoDB
b. Create server folder
c. Connect to MongoDB
d. Set up our API
e. Create API endpoints
3. Create the Client
a. Create client folder
b. Connect to our API
c. Render all dibs
d. Add support for creating a dib
e. Enable a user to log in
4. Let's call dibs
a. Server support
b. Client support
5. To real time, and beyond!
a. Server support
b. Client support
Change
Streams
20. Source Code
We’re starting with a partially complete
codebase.
You’ll see TODO comments throughout.
By the end of today all of those will be
completed.
21. Source Code
All source code for each step is
available online for quick reference.
https://github.com/hswolff/dibs/tree/tutorial
Download a copy of the code for easy reference
https://github.com/hswolff/dibs/archive/tutorial.zip
22. Download a copy of these slides
http://bit.ly/mdbw18-dibs
Slides
27. # Create the folder where the database will save its data.
mkdir db
# Start the mongo daemon, and leave it open in a terminal.
mongod --port 27017 --dbpath $(pwd)/db --replSet rs0
# Instantiate the replica set. Only need to run this one time.
mongo --eval "rs.initiate()"
Set up MongoDB
28. Set up MongoDB
# Connect to the db from a different shell.
mongo
# You should see
rs0:PRIMARY>
34. 1. Open node REPL
a. node
2. Import db file and connect to MongoDB
a. const db = require('./db);
b. db.connect();
3. Find all documents
a. db.Models.Dib.find().then(console.log);
4. Create a document
a. db.Models.Dib.create({ title: 'First Item', creator: 'Yay'
}).then(console.log);
5. Find all documents again
Connect to MongoDB: Let’s test it
35. 1. Try and create a document that doesn’t
pass validation.
2. Use the Mongoose method to find one
document
(hint http://mongoosejs.com/docs/queries.html)
Connect to MongoDB: Let’s test it
40. const express = require('express');
const cors = require('cors');
const bodyParser = require('body-parser');
const PORT = process.env.PORT || 8080;
const DOMAIN = process.env.DOMAIN || 'http://localhost' ;
Set up our API: server.js
41. function createServer() {
const app = express();
app.use(cors(), bodyParser.json());
app.get('/', (req, res) => {
res.send('Hello World!');
});
app.listen(PORT, () => {
console.log(`Server ready at ${DOMAIN}:${PORT}/`);
});
}
createServer();
Set up our API: server.js
42. 1. Start server
a. node server.js
2. Open browser: http://localhost:8080/
3. What do you see?
Set up our API: Test It
43. 1. Change a handler to return JSON to the
browser
2. Add a new handler that says ‘Goodbye’
3. Add a handler that takes in a parameter
so we can say `Hello ${name}`
(hint: https://expressjs.com/en/guide/routing.html)
Set up our API: Exercise
46. Create API endpoints
# We want to expose our MongoDB data
through an API
# We’re going to expose all API methods
under an /api route namespace.
open server/api.js
51. Check GET and browse to:
http://localhost:8080/api/dibs
Check POST with cURL
curl --data '{"title": "Hello from Curl", "creator": "Mr. Curly"}'
-X POST --header "Content-Type: application/json"
http://localhost:8080/api/dibs
Create API endpoints: Test It
52. Create API endpoints: Catch Up
https://github.com/hswolff/dibs/tree/tutori
al/step2e/server
55. Outline
1. Prerequisites
2. Create the Server
a. Set up MongoDB
b. Create server folder
c. Connect to MongoDB
d. Set up our API
e. Create API endpoints
3. Create the Client
a. Create client folder
b. Connect to our API
c. Render all dibs
d. Add support for creating a dib
e. Enable a user to log in
4. Let's call dibs
a. Server support
b. Client support
5. To real time, and beyond!
a. Server support
b. Client support
65. 1. Ensure your API server is running.
2. Ensure your client environment is running.
3. Go to client/src/index.js.
4. We’re going to expose our client API globally.
Connect to our API: Test It
66. import api from './services/api';
window.api = api;
Connect to our API: client/src/index.js
67. 5. Go to your browser and open the Developer Tools
(for Chrome go to View > Developer > Developer Tools)
6. Go to the “Console” tab
7. Type ‘api’ in the console. You should see your API code!
8. Exercise: Try making a request for “getDibs”
Answer: api.getDibs().then(console.log)
9. Exercise: Try creating a new dib
Answer: api.createDib({ creator: 'Browser', title: 'From
the client!' }).then(console.log)
Connect to our API: Test It
71. # We want to fetch our data from our server API
# We’re going to load the data in our HomePage
# We’re going to use React’s lifecycle methods to do so
# Namely the componentDidMount lifecycle method
open src/components/HomePage.js
Render all dibs: Load the data
78. # Now we want to render each item a little better
# To do so we’ll use the component “DibCell”
open components/DibCell.js
Render all dibs: With style!
92. # Using our CreateNewDib component
# We need to hook it up to actually create the new dib.
open src/components/CreateNewDib.js
Add support for creating a dib
102. Enable a user to log in
# We need to enable a user to give us a username so we can
show the right person that created a dib
# We store the user in localStorage to persist it between
refreshes
# We’re going to use the SignIn component to let a user sign
in.
open src/components/SignIn.js
107. 1. Try creating a new dib!
2. Do you see it appear?
Enable a user to log in: Test it
108. 1. Only show CreateNewDib if a username is set
2. Show an error if a user puts in an empty username
3. Style SignIn component
Enable a user to log in: Exercise
112. Outline
1. Prerequisites
2. Create the Server
a. Set up MongoDB
b. Create server folder
c. Connect to MongoDB
d. Set up our API
e. Create API endpoints
3. Create the Client
a. Create client folder
b. Connect to our API
c. Render all dibs
d. Add support for creating a dib
e. Enable a user to log in
4. Let's call dibs
a. Server support
b. Client support
5. To real time, and beyond!
a. Server support
b. Client support
118. Server support
# We need to add a new endpoint
# Endpoint adds support for a user to claim a dib
# We need to validate the data sent
Need to make sure all data required is sent
Need to make sure that the dib exists
Need to make sure a dib has not already been claimed
126. # Add a handler to actually make our API call to claim a dib
# Update our “Dibs?” text to say “Claimed!” if the dib is
already taken
open src/components/DibCell.js
Client support
136. Outline
1. Prerequisites
2. Create the Server
a. Set up MongoDB
b. Create server folder
c. Connect to MongoDB
d. Set up our API
e. Create API endpoints
3. Create the Client
a. Create client folder
b. Connect to our API
c. Render all dibs
d. Add support for creating a dib
e. Enable a user to log in
4. Let's call dibs
a. Server support
b. Client support
5. To real time, and beyond!
a. Server support
b. Client support
139. # We want to open a Change Stream to be notified of when our
collection in MongoDB changes
# Change Streams are a new feature in MongoDB 3.6
# Change Streams allow applications to access real-time data
changes without the complexity and risk of tailing the oplog.
(docs)
Server support
141. Server support: db.js
async function connect() {
await mongoose.connect(dbUri);
console.log('Connected to MongoDB');
const dibChangeStream = Models.Dib.collection.watch({
fullDocument: 'updateLookup',
});
dibChangeStream.on('change', result => {
console.log(JSON.stringify(result, null, 2));
});
}
142. # Try making a new dib!
# Try claiming a dib!
# Should see output from your server.
Server support: Test Change Stream
143. So let’s talk real time.
We want our updates to show immediately.
There’s one technology good for that…
WebSockets!
144. WebSockets are an advanced technology that makes it possible to
open an interactive communication session between the user's
browser and a server. With this API, you can send messages to a
server and receive event-driven responses without having to poll
the server for a reply.
- https://developer.mozilla.org/en-US/docs/Web/API/WebSockets
_API
145. # We’re using socket.io as our WebSocket server
# Create our WebSocket server
Server support
153. # We need to be able to connect to our WebSocket server
# To do that we’ll use…
# socket.io on the client!
Client support
154. # Let’s add a method for us to connect to our WebSocket server
# In particular we want to subscribe to our ‘dib changeEvent’
# When that event happens we want our callback to be called
open src/services/api.js
Client support
166. Outline
1. Prerequisites
2. Create the Server
a. Set up MongoDB
b. Create server folder
c. Connect to MongoDB
d. Set up our API
e. Create API endpoints
3. Create the Client
a. Create client folder
b. Connect to our API
c. Render all dibs
d. Add support for creating a dib
e. Enable a user to log in
4. Let's call dibs
a. Server support
b. Client support
5. To real time, and beyond!
a. Server support
b. Client support
168. 1. Instantiated our own local MongoDB
2. Created an entire API server, powered by Express
3. Opened a MongoDB Change Stream
4. Created a WebSocket server that tells the client when data
in our MongoDB Change Stream changed
5. Created a React application
6. Connected to our API server on the client
7. Added the ability to list all our dibs
8. Added the ability to create a dib
9. Added the ability to claim a dib
10. ...and we made it all work in real time!
Let’s Recap
173. 1. Location of Dib.
2. Price/bounty of Dib.
3. Auth with Google
4. Real-time comments on a Dib
5. Able to edit Dibs that you created.
6. Able to un-claim a Dib if you're the creator of the dib.
7. ...and more!
Take it further
174. Got Dibs? Building a
Real-Time Bidding App
with Change Streams
A tutorial by Harry Wolff