{"componentChunkName":"component---src-templates-assignment-template-js","path":"/practicals/practical09","webpackCompilationHash":"041090671d318979d692","result":{"data":{"markdownRemark":{"htmlAst":{"type":"root","children":[{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"In this practical you will adapt a simple memory-backed server for Simplepedia to use a MongoDB backend. The goals for this practical are to gain familiarity\nwith MongoDB and MongoDB-backed servers."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h4","properties":{"id":"goals"},"children":[{"type":"element","tagName":"a","properties":{"href":"#goals","ariaLabel":"goals permalink","className":["anchor"]},"children":[{"type":"element","tagName":"svg","properties":{"ariaHidden":"true","focusable":"false","height":"16","version":"1.1","viewBox":"0 0 16 16","width":"16"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","d":"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"},"children":[]}]}]},{"type":"text","value":"Goals"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"ul","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"Gain familiarity with a noSQL database (in this case MongoDB)."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"Get more experience thinking about and working with back-end code."}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h2","properties":{"id":"prerequisites"},"children":[{"type":"element","tagName":"a","properties":{"href":"#prerequisites","ariaLabel":"prerequisites permalink","className":["anchor"]},"children":[{"type":"element","tagName":"svg","properties":{"ariaHidden":"true","focusable":"false","height":"16","version":"1.1","viewBox":"0 0 16 16","width":"16"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","d":"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"},"children":[]}]}]},{"type":"text","value":"Prerequisites"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"ol","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"Click through to the GitHub "},{"type":"element","tagName":"a","properties":{"href":"https://classroom.github.com/a/Eh52oxMJ"},"children":[{"type":"text","value":"classroom assignment"}]},{"type":"text","value":" to create your private repository. Then clone that newly created repository to your local computer as you have done previously."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"Install the package dependencies by running "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"npm install"}]},{"type":"text","value":" inside the root directory of the newly cloned repository."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"You will need to have the MongoDB server installed. If you don't, instructions for installing MongoDB are included in the class "},{"type":"element","tagName":"a","properties":{"href":"../resources/getting-started"},"children":[{"type":"text","value":"\"Getting Started\""}]},{"type":"text","value":" page. "}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"Install (and save as a dependency) the "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"mongodb"}]},{"type":"text","value":" package with "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"npm install --save mongodb"}]},{"type":"text","value":"."}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"Notice that the skeleton repository includes a NPM \"postinstall\" action that automatically creates a "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"./data"}]},{"type":"text","value":" directory to store your MongoDB database. This is another example of using automation to improve our development and operations processes. Manually creating the "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"data"}]},{"type":"text","value":" directory (or any manual step for that matter) just creates opportunities for the process to go awry."}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h2","properties":{"id":"starting-the-server"},"children":[{"type":"element","tagName":"a","properties":{"href":"#starting-the-server","ariaLabel":"starting the server permalink","className":["anchor"]},"children":[{"type":"element","tagName":"svg","properties":{"ariaHidden":"true","focusable":"false","height":"16","version":"1.1","viewBox":"0 0 16 16","width":"16"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","d":"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"},"children":[]}]}]},{"type":"text","value":"Starting the Server"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"MongoDB uses a YAML "},{"type":"element","tagName":"a","properties":{"href":"https://docs.mongodb.com/manual/reference/configuration-options/"},"children":[{"type":"text","value":"configuration file"}]},{"type":"text","value":" to set the data directory, port, etc.. The skeleton includes a "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"mongod.conf"}]},{"type":"text","value":" file with the following parameters:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"net:\n  port: 5000\nstorage:\n  dbPath: ./data"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"The command to start the "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"mongod"}]},{"type":"text","value":" process (the database server) is "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"mongod --config mongod.conf"}]},{"type":"text","value":" (but don't run it just yet)."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"I would like you to practice adding automation to your project. In "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"package.json"}]},{"type":"text","value":", add a new line to the \"scripts\" section:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"\"mongo:start\": \"mongod --config mongod.conf\""}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"This adds a new script that can be run with "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"npm run mongo:start"}]},{"type":"text","value":". There is no meaning to the ':' in the name, it is just a convenient way to provide a common \"namespace\" to our commands."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Go ahead and start the database server. It will need its own terminal window, because you will leave the database server running in that terminal window for all of the subsequent steps (you can only use the database when the server is running)."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h2","properties":{"id":"seeding-the-article-data"},"children":[{"type":"element","tagName":"a","properties":{"href":"#seeding-the-article-data","ariaLabel":"seeding the article data permalink","className":["anchor"]},"children":[{"type":"element","tagName":"svg","properties":{"ariaHidden":"true","focusable":"false","height":"16","version":"1.1","viewBox":"0 0 16 16","width":"16"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","d":"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"},"children":[]}]}]},{"type":"text","value":"Seeding the Article data"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Unlike the RDBMS-server, we can directly seed the database from the JSON data file using the "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"mongoimport"}]},{"type":"text","value":" utility (command below). Note that this works because "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"seed.json"}]},{"type":"text","value":" is setup as JSON array, i.e. "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"[{...}, {...}, ...]"}]},{"type":"text","value":". The command looks like this (but, again, don't just run it):"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"mongoimport --host localhost:5000 --db simplepedia --collection articles --jsonArray seed.json"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Add a new script called "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"mongo:seed"}]},{"type":"text","value":" that runs this command. (Obviously, if you are running "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"mongod"}]},{"type":"text","value":" somewhere other than the default location, you will need to update the hostname and port). "}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"We will add one more command: "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"mongo:purge"}]},{"type":"text","value":", which you can set to "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"mongo localhost:5000/simplepedia --eval \"db.dropDatabase()\""}]},{"type":"text","value":". "}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"These two scripts are dangerously destructive -- one loads a large amount of data into the database and the other one clears out all of the data. Use with care."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"If this database was higher stakes, we would add some guards to make sure the user didn't run these by accident."}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Now, combine these together into one script that performs both actions:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"\"mongo:init\": \"npm run mongo:purge; npm run mongo:seed; \""}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h2","properties":{"id":"explore-the-database"},"children":[{"type":"element","tagName":"a","properties":{"href":"#explore-the-database","ariaLabel":"explore the database permalink","className":["anchor"]},"children":[{"type":"element","tagName":"svg","properties":{"ariaHidden":"true","focusable":"false","height":"16","version":"1.1","viewBox":"0 0 16 16","width":"16"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","d":"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"},"children":[]}]}]},{"type":"text","value":"Explore the Database"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Connect to the database with the "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"mongo"}]},{"type":"text","value":" client ("},{"type":"element","tagName":"kbd","properties":{},"children":[{"type":"text","value":"Ctrl+D"}]},{"type":"text","value":" to exit):"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"mongo localhost:5000"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"The "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"mongo"}]},{"type":"text","value":" shell environment is essentially a JavaScript interpreter with additional commands for manipulating the database(s). Invoke "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"show dbs"}]},{"type":"text","value":" to list the databases and "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"use simplepedia"}]},{"type":"text","value":" to set the current database. Once you have set the database, invoke "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"show collections"}]},{"type":"text","value":" to show the available collections."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"The MongoDB "},{"type":"element","tagName":"a","properties":{"href":"https://docs.mongodb.com/manual/"},"children":[{"type":"text","value":"documentation"}]},{"type":"text","value":" is pretty good. However, if you are more familiar with SQL (as I am), the "},{"type":"element","tagName":"a","properties":{"href":"https://docs.mongodb.com/manual/reference/sql-comparison/"},"children":[{"type":"text","value":"SQL to MongoDB Mapping Chart"}]},{"type":"text","value":" is particularly useful (if it is all new to you, this page is still useful since it is essentially a listing of short examples of common operations -- just ignore the SQL side). "}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Explore the database. For example to query for all the articles:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"db.articles.find()"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Note that every article now has an automatically generated "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"_id"}]},{"type":"text","value":" field. We will return to that in a moment."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"To find the article titled 'Ikoga':"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"db.articles.find({\"title\": \"Ikoga\"})"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"To find all the articles that begin with 'U':"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"db.articles.find({\"title\":{$regex: /^u/i }})"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"/^u/i"}]},{"type":"text","value":" is a Regular Expression that "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"case insensitively"}]},{"type":"text","value":" matches all strings\nthat begin with 'u'. The '^' indicates the start of the field, and the 'i' on the end says to be case insensitive."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"To update the 'Ikoga' article, we could write something like this:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"db.articles.updateOne({'title':'Ikoga'}, {$set: {'extract': 'A small village'}})"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"If you search for it again, you will see that the article's extract has changed. The syntax of this is a little strange. The first argument is a query that will accept anything "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"find"}]},{"type":"text","value":" will. The second argument is the update command, which must include an "},{"type":"element","tagName":"a","properties":{"href":"https://docs.mongodb.com/manual/reference/operator/update/"},"children":[{"type":"text","value":"update operator"}]},{"type":"text","value":" (in this case "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"$set"}]},{"type":"text","value":"). The "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"$set"}]},{"type":"text","value":" update works like "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"Object.assign"}]},{"type":"text","value":" in that any fields we specify will be changed (or added, if they don't already exist)."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"This barely scratches the surface of possible queries. Consult the "},{"type":"element","tagName":"a","properties":{"href":"https://docs.mongodb.com/manual/tutorial/query-documents/"},"children":[{"type":"text","value":"documentation"}]},{"type":"text","value":" for the full range of possibilities. "}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"Note: There are subtle differences between the "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"mongo"}]},{"type":"text","value":" shell tool and the "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"node"}]},{"type":"text","value":" driver that you will use for the server. Stay on your toes and try to pay attention to which documentation you are looking at."}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h2","properties":{"id":"update-the-express-server"},"children":[{"type":"element","tagName":"a","properties":{"href":"#update-the-express-server","ariaLabel":"update the express server permalink","className":["anchor"]},"children":[{"type":"element","tagName":"svg","properties":{"ariaHidden":"true","focusable":"false","height":"16","version":"1.1","viewBox":"0 0 16 16","width":"16"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","d":"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"},"children":[]}]}]},{"type":"text","value":"Update the Express Server"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h3","properties":{"id":"connect-to-the-database"},"children":[{"type":"element","tagName":"a","properties":{"href":"#connect-to-the-database","ariaLabel":"connect to the database permalink","className":["anchor"]},"children":[{"type":"element","tagName":"svg","properties":{"ariaHidden":"true","focusable":"false","height":"16","version":"1.1","viewBox":"0 0 16 16","width":"16"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","d":"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"},"children":[]}]}]},{"type":"text","value":"Connect to the database"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Before you can update the routes to use the database, you need to connect to the database. There are a number of different patterns we could follow, but we will stick to the pattern of opening the database before we start the server and then hanging on to the open database connection rather than re-opening it every time we need to consult with it."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Replace the initialization code in "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"index.js"}]},{"type":"text","value":" with the following.  Here we use the "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"MONGODB_URI"}]},{"type":"text","value":" environment variable, if defined (e.g. on Heroku), or default to "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"'mongodb://localhost:5000/simplepedia"}]},{"type":"text","value":", to create the connection. As before, to ensure that we can successfully handle requests, we don't start the Express server until we are connected to the database (i.e. when the callback is invoked). "}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"We need to hang on to a reference to the database connection, which we extract from the URL. We are going to do something a little different this time and store the database connection in the "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"locals"}]},{"type":"text","value":" field of the Express "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"app"}]},{"type":"text","value":" object."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"javascript"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-javascript"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-javascript"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"/* eslint-disable no-console */"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" http "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"require"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'http'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" url "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"require"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'url'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" MongoClient "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"require"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'mongodb'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" app "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"require"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'./routes'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" mongoURL "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":"\n  process"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"env"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","constant"]},"children":[{"type":"text","value":"MONGODB_URI"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"||"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'mongodb://localhost:5000/simplepedia'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" client "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"new"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","class-name"]},"children":[{"type":"text","value":"MongoClient"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"mongoURL"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" useNewUrlParser"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","boolean"]},"children":[{"type":"text","value":"true"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" useUnifiedTopology"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","boolean"]},"children":[{"type":"text","value":"true"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n\n\nclient"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"connect"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"err"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" database"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"if"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"err"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n    console"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"error"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"err"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"else"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" db "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" database"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"db"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"url"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"parse"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"mongoURL"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"pathname"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"slice"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"1"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"// pass the db name to the express routes"}]},{"type":"text","value":"\n    app"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"locals"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"db "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" db"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n\n    "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" server "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" http"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"createServer"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"app"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"listen"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"process"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"env"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","constant"]},"children":[{"type":"text","value":"PORT"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"||"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"3001"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n    console"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"log"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'Listening on port %d'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" server"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"address"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"port"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Once you have made the above changes, you can delete the "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"articles"}]},{"type":"text","value":" variable and the "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"get_unique_id"}]},{"type":"text","value":" function from "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"routes.js"}]},{"type":"text","value":" (also delete them from the "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"module.exports"}]},{"type":"text","value":"). So that your code still runs, comment out the lines in your routes that refer to "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"articles"}]},{"type":"text","value":"."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h3","properties":{"id":"update-the-get-articles-route"},"children":[{"type":"element","tagName":"a","properties":{"href":"#update-the-get-articles-route","ariaLabel":"update the get articles route permalink","className":["anchor"]},"children":[{"type":"element","tagName":"svg","properties":{"ariaHidden":"true","focusable":"false","height":"16","version":"1.1","viewBox":"0 0 16 16","width":"16"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","d":"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"},"children":[]}]}]},{"type":"text","value":"Update the GET '/articles' Route"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"In order to fetch all of the articles, you want to perform a "},{"type":"element","tagName":"a","properties":{"href":"http://mongodb.github.io/node-mongodb-native/3.3/api/Collection.html#find"},"children":[{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"find"}]},{"type":"text","value":" operation"}]},{"type":"text","value":" on the 'articles' collection in the database (with no filters). The result is not the data itself but a cursor that you could use to obtain that data. Invoke the "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"toArray"}]},{"type":"text","value":" method on the cursor to obtain all the data as an Array, as a Promise. The function you provide to "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"then()"}]},{"type":"text","value":" should take one argument, the array of documents. You can send this array back to the client directly with "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"response.send()"}]},{"type":"text","value":" as shown below (recall that Express automatically sets the status code and content-type). "}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"javascript"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-javascript"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-javascript"]},"children":[{"type":"text","value":"app"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"get"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'/api/articles'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"request"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" response"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" next"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"// <- Notice the \"next\" argument to the handler"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"// Notice that we extract the \"db\" variable from \"app.locals\""}]},{"type":"text","value":"\n  app"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"locals"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"db"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"collection"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'articles'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"find"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"toArray"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"then"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"documents"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n      response"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"send"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"documents"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" next"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"// <- Notice the \"next\" function as the rejection handler"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h3","properties":{"id":"running-your-express-server"},"children":[{"type":"element","tagName":"a","properties":{"href":"#running-your-express-server","ariaLabel":"running your express server permalink","className":["anchor"]},"children":[{"type":"element","tagName":"svg","properties":{"ariaHidden":"true","focusable":"false","height":"16","version":"1.1","viewBox":"0 0 16 16","width":"16"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","d":"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"},"children":[]}]}]},{"type":"text","value":"Running your Express Server"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Start your Express server with "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"npm start"}]},{"type":"text","value":". In a separate terminal window, test your newly created route with curl as shown below (at this point you should have three terminal windows open: one with the MongoDB server running, one with your Express server running, and one where you are executing the "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"curl"}]},{"type":"text","value":"\ncommand):"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"curl http://localhost:3001/api/articles"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"You can also open "},{"type":"element","tagName":"a","properties":{"href":"http://localhost:3001/api/articles"},"children":[{"type":"text","value":"http://localhost:3001/api/articles"}]},{"type":"text","value":" in your browser instead of using curl."}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"You should see a long array of articles. "}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"If you are running the database server on a different port, e.g. 5005, on OSX/Linux you can use the "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"MONGODB_URI"}]},{"type":"text","value":" environment variable to initialize your Express server appropriately, e.g.:"}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"MONGODB_URI=\"mongodb://localhost:5005/simplepedia\" npm start"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h2","properties":{"id":"enable-testing"},"children":[{"type":"element","tagName":"a","properties":{"href":"#enable-testing","ariaLabel":"enable testing permalink","className":["anchor"]},"children":[{"type":"element","tagName":"svg","properties":{"ariaHidden":"true","focusable":"false","height":"16","version":"1.1","viewBox":"0 0 16 16","width":"16"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","d":"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"},"children":[]}]}]},{"type":"text","value":"Enable Testing"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Take a look at "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"routes.test.js"}]},{"type":"text","value":". Following the suggested practice in the "},{"type":"element","tagName":"a","properties":{"href":"https://jestjs.io/docs/en/mongodb.html"},"children":[{"type":"text","value":"Jest documentation"}]},{"type":"text","value":" we will use "},{"type":"element","tagName":"a","properties":{"href":"https://github.com/nodkz/mongodb-memory-server"},"children":[{"type":"text","value":"mongodb-memory-server"}]},{"type":"text","value":" to spin up in-memory MongoDB servers for testing. Run "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"npm install --save-dev mongodb-memory-server"}]},{"type":"text","value":" to install that package as a development dependency."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"The "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"beforeAll"}]},{"type":"text","value":" function creates the database (once, before all tests in that file). The "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"beforeEach"}]},{"type":"text","value":" and "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"afterEach"}]},{"type":"text","value":" functions seed the database with a pair of sample articles in the 'articles' collection (and deletes all articles after each test). Note that the "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"insert"}]},{"type":"text","value":" function automatically modifies its input object with the "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"_id"}]},{"type":"text","value":" field (that is, it will actually modify the objects stored in "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"articles"}]},{"type":"text","value":")."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"The advantage of this approach for testing is that each test suite executes in a \"fresh\" and independent database instance, you don't need to manually start a separate server, and no additional configuration is required to run tests on Travis CI."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Run the tests with "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"npm test"}]},{"type":"text","value":". The test for the GET '/articles' route you implemented above should pass but most every other test should not. Let's update the remaining routes in a TDD approach. "}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h2","properties":{"id":"implementing-the-routes"},"children":[{"type":"element","tagName":"a","properties":{"href":"#implementing-the-routes","ariaLabel":"implementing the routes permalink","className":["anchor"]},"children":[{"type":"element","tagName":"svg","properties":{"ariaHidden":"true","focusable":"false","height":"16","version":"1.1","viewBox":"0 0 16 16","width":"16"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","d":"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"},"children":[]}]}]},{"type":"text","value":"Implementing the Routes"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Recall that the Simplepedia API looks like:"}]},{"type":"text","value":"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"},{"type":"element","tagName":"table","properties":{},"children":[{"type":"element","tagName":"thead","properties":{},"children":[{"type":"element","tagName":"tr","properties":{},"children":[{"type":"element","tagName":"th","properties":{},"children":[{"type":"text","value":"Endpoint"}]},{"type":"element","tagName":"th","properties":{},"children":[{"type":"text","value":"Command"}]},{"type":"element","tagName":"th","properties":{},"children":[{"type":"text","value":"Action"}]}]}]},{"type":"element","tagName":"tbody","properties":{},"children":[{"type":"element","tagName":"tr","properties":{},"children":[{"type":"element","tagName":"td","properties":{},"children":[{"type":"text","value":"/api/articles"}]},{"type":"element","tagName":"td","properties":{},"children":[{"type":"text","value":"GET"}]},{"type":"element","tagName":"td","properties":{},"children":[{"type":"text","value":"Fetch the entire article collection as an array"}]}]},{"type":"element","tagName":"tr","properties":{},"children":[{"type":"element","tagName":"td","properties":{},"children":[{"type":"text","value":"/api/articles"}]},{"type":"element","tagName":"td","properties":{},"children":[{"type":"text","value":"POST"}]},{"type":"element","tagName":"td","properties":{},"children":[{"type":"text","value":"Add a new article to the collection (the new article should be provided as the JSON-encoded request body)"}]}]},{"type":"element","tagName":"tr","properties":{},"children":[{"type":"element","tagName":"td","properties":{},"children":[{"type":"text","value":"/api/articles/"},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":":id"}]}]},{"type":"element","tagName":"td","properties":{},"children":[{"type":"text","value":"PUT"}]},{"type":"element","tagName":"td","properties":{},"children":[{"type":"text","value":"Update the article with "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"id"}]},{"type":"text","value":" of "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":":id"}]},{"type":"text","value":" (entire updated article should be provided as the JSON-encoded request body)"}]}]},{"type":"element","tagName":"tr","properties":{},"children":[{"type":"element","tagName":"td","properties":{},"children":[{"type":"text","value":"/api/articles/"},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":":id"}]}]},{"type":"element","tagName":"td","properties":{},"children":[{"type":"text","value":"DELETE"}]},{"type":"element","tagName":"td","properties":{},"children":[{"type":"text","value":"Remove the article with "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"id"}]},{"type":"text","value":" of "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":":id"}]}]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Implement the other three routes. As you do, pay attention to the code you are replacing. In some instance, you will want to preserve the functionality (i.e., the routes should still return the same values). In other instances, you may find that you can throw away the functionality (e.g., you no longer need to manually attach ids.)."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":" Relevant query methods will be\n"},{"type":"element","tagName":"a","properties":{"href":"http://mongodb.github.io/node-mongodb-native/3.3/api/Collection.html#insertOne"},"children":[{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"insertOne"}]}]},{"type":"text","value":",\n"},{"type":"element","tagName":"a","properties":{"href":"http://mongodb.github.io/node-mongodb-native/3.3/api/Collection.html#deleteOne"},"children":[{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"deleteOne"}]}]},{"type":"text","value":"\nand\n"},{"type":"element","tagName":"a","properties":{"href":"http://mongodb.github.io/node-mongodb-native/3.3/api/Collection.html#findOneAndUpdate"},"children":[{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"findOneAndUpdate"}]}]},{"type":"text","value":". "}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h3","properties":{"id":"gotcha-1"},"children":[{"type":"element","tagName":"a","properties":{"href":"#gotcha-1","ariaLabel":"gotcha 1 permalink","className":["anchor"]},"children":[{"type":"element","tagName":"svg","properties":{"ariaHidden":"true","focusable":"false","height":"16","version":"1.1","viewBox":"0 0 16 16","width":"16"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","d":"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"},"children":[]}]}]},{"type":"text","value":"Gotcha #1"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Make sure that you read the documentation carefully to figure out what you need to pass to the functions and what the return values are. For example, by default "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"findOneAndUpdate"}]},{"type":"text","value":" returns the original article, not the newly updated article. Set the options appropriately to obtain the desired behavior."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h3","properties":{"id":"gotcha-2"},"children":[{"type":"element","tagName":"a","properties":{"href":"#gotcha-2","ariaLabel":"gotcha 2 permalink","className":["anchor"]},"children":[{"type":"element","tagName":"svg","properties":{"ariaHidden":"true","focusable":"false","height":"16","version":"1.1","viewBox":"0 0 16 16","width":"16"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","d":"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"},"children":[]}]}]},{"type":"text","value":"Gotcha #2"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"The three functions listed above take an optional callback. If you don't pass the callback, the functions return Promises, with the values that would have been passed to the callback available to the function you write in the "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"then()"}]},{"type":"text","value":". To learn about what about type the Promise will resolve to, click through to the documentation of the "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"callback"}]},{"type":"text","value":" argument, e.g. "},{"type":"element","tagName":"a","properties":{"href":"http://mongodb.github.io/node-mongodb-native/3.3/api/Collection.html#~insertOneWriteOpCallback"},"children":[{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"insertOneWriteOpCallback"}]}]},{"type":"text","value":" for "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"insertOne"}]},{"type":"text","value":". In the Promise version of the API we are using, there is no "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"error"}]},{"type":"text","value":" argument, just the "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"result"}]},{"type":"text","value":" argument (errors are handled by rejecting the Promise). In the case of "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"insertOne"}]},{"type":"text","value":", the result will be of type "},{"type":"element","tagName":"a","properties":{"href":"http://mongodb.github.io/node-mongodb-native/3.3/api/Collection.html#~insertOneWriteOpResult"},"children":[{"type":"text","value":"insertOneWriteOpResult"}]},{"type":"text","value":" with the inserted document in the "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"ops"}]},{"type":"text","value":" property (an array)."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h3","properties":{"id":"gotcha-3"},"children":[{"type":"element","tagName":"a","properties":{"href":"#gotcha-3","ariaLabel":"gotcha 3 permalink","className":["anchor"]},"children":[{"type":"element","tagName":"svg","properties":{"ariaHidden":"true","focusable":"false","height":"16","version":"1.1","viewBox":"0 0 16 16","width":"16"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","d":"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"},"children":[]}]}]},{"type":"text","value":"Gotcha #3"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Recall that "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":":id"}]},{"type":"text","value":" parameters in the routes needs to be a unique identifier for for the article. Often this identifier is an integer, but in this case, the unique identifier we have is the automatically generated "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"ObjectID"}]},{"type":"text","value":", which is a binary object. This gets converted to a string when we take the value out of the database. However, we need to convert the string back to a proper binary "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"ObjectID"}]},{"type":"text","value":" when we are communicating with the database."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Fortunately, we have a tool for converting from string to "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"ObjectID"}]},{"type":"text","value":": "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"ObjectID.createFromHexString()"}]},{"type":"text","value":". The "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"ObjectID.createFromHexString"}]},{"type":"text","value":" method converts the string in the URL into the "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"ObjectID"}]},{"type":"text","value":" object used by MongoDB and needed in the query. "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"ObjectID"}]},{"type":"text","value":" is provided by the "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"mongodb"}]},{"type":"text","value":" package, so it needs to be imported at the top of "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"routes.js"}]},{"type":"text","value":" (I have already done this for you)."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"As an example of when you need to use this, when we update an article, we need to convert the "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"_id"}]},{"type":"text","value":" back to "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"ObjectID"}]},{"type":"text","value":" form so it is recognized by mongo. This is one way we could do this:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"javascript"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-javascript"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-javascript"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" updatedArticle "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"..."}]},{"type":"text","value":"request"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"body"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" _id"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" ObjectID"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"createFromHexString"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"request"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"params"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"id"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h3","properties":{"id":"gotcha-4"},"children":[{"type":"element","tagName":"a","properties":{"href":"#gotcha-4","ariaLabel":"gotcha 4 permalink","className":["anchor"]},"children":[{"type":"element","tagName":"svg","properties":{"ariaHidden":"true","focusable":"false","height":"16","version":"1.1","viewBox":"0 0 16 16","width":"16"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","d":"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"},"children":[]}]}]},{"type":"text","value":"Gotcha #4"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"By default "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"findOneAndUpdate"}]},{"type":"text","value":" doesn't return the updated article (notice in the options that "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"returnOriginal"}]},{"type":"text","value":" defaults to "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"true"}]},{"type":"text","value":"). Provide an options argument with that property set to "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"false"}]},{"type":"text","value":" to force the driver to return the updated object."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h3","properties":{"id":"validations"},"children":[{"type":"element","tagName":"a","properties":{"href":"#validations","ariaLabel":"validations permalink","className":["anchor"]},"children":[{"type":"element","tagName":"svg","properties":{"ariaHidden":"true","focusable":"false","height":"16","version":"1.1","viewBox":"0 0 16 16","width":"16"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","d":"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"},"children":[]}]}]},{"type":"text","value":"Validations"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"The basic query operations should resolve many of your test cases. However, queries alone will not address missing or non-unique fields. As discussed in lecture, we often use ORM libraries to implement validations in a DRY manner (via Aspect-Oriented Programming or AOP). For MongodDB, this is often the "},{"type":"element","tagName":"a","properties":{"href":"http://mongoosejs.com"},"children":[{"type":"text","value":"Mongoose"}]},{"type":"text","value":" library.  "}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"However, for simplicity, you will just implement the necessary validations in the routes. For instance to define a default value for the "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"extract"}]},{"type":"text","value":" and check if "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"edited"}]},{"type":"text","value":" is defined, you could implement something like the following:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"javascript"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-javascript"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-javascript"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" newArticle "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" extract"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"''"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"..."}]},{"type":"text","value":"request"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"body "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n\n  "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"if"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"!"}]},{"type":"text","value":" newArticle"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"edited"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n    response"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"sendStatus"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"400"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"The conditional will set the status to \"bad request\" and terminate the handler if the "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"edited"}]},{"type":"text","value":" property is not defined (i.e. \"falsy\"). "}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Preventing duplicate article titles is trickier. To know if an article title already exists, we would need to query the database before writing. We can certainly do so. However, it will be more efficient to create an "},{"type":"element","tagName":"a","properties":{"href":"https://docs.mongodb.com/manual/reference/method/db.collection.createIndex/"},"children":[{"type":"text","value":"index"}]},{"type":"text","value":" on the article title that enforces uniqueness. For example the following was added the end of the Promise chain in "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"beforeAll"}]},{"type":"text","value":" to create a \"unique\" index on the "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"title"}]},{"type":"text","value":" field. "}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"javascript"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-javascript"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-javascript"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"then"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n  db"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"collection"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'articles'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"createIndex"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" title"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"1"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" unique"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","boolean"]},"children":[{"type":"text","value":"true"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"The index is why the \"Should reject article with duplicate title\" tests are passing (or should be). "}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"At this point all of your tests should be passing. However, we only added the index to the test database -- not the database that the server will actually use. To continue to automate all of the things, we will add another command to our "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"mongo:init"}]},{"type":"text","value":" script that creates the index using the "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"mongo"}]},{"type":"text","value":" command line tool."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"sh"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-sh"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-sh"]},"children":[{"type":"text","value":" \"mongo:init\": \"npm run mongo:purge; mongo localhost:5000/simplepedia --eval \\\"db.articles.createIndex({ title: 1 },{ unique: true })\\\"; npm run mongo:seed\""}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"Note that this validation will not work for UPDATE operations (i.e., "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"put"}]},{"type":"text","value":"). If an update arrives without a title, the assumption will be that you want to use the old title. If this behavior is desirable or not will depend on how you are going to use it."}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h2","properties":{"id":"when-you-are-done"},"children":[{"type":"element","tagName":"a","properties":{"href":"#when-you-are-done","ariaLabel":"when you are done permalink","className":["anchor"]},"children":[{"type":"element","tagName":"svg","properties":{"ariaHidden":"true","focusable":"false","height":"16","version":"1.1","viewBox":"0 0 16 16","width":"16"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","d":"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"},"children":[]}]}]},{"type":"text","value":"When You Are Done"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Theoretically, when you finish, you should be able to redirect the Simplepedia client you wrote in assignment 4 to interact with your new server. Unfortunately, it is not that simple. Because MongoDB uses "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"_id"}]},{"type":"text","value":" instead of "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"id"}]},{"type":"text","value":", a number of things will fail in strange ways."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h2","properties":{"id":"finishing-up"},"children":[{"type":"element","tagName":"a","properties":{"href":"#finishing-up","ariaLabel":"finishing up permalink","className":["anchor"]},"children":[{"type":"element","tagName":"svg","properties":{"ariaHidden":"true","focusable":"false","height":"16","version":"1.1","viewBox":"0 0 16 16","width":"16"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","d":"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"},"children":[]}]}]},{"type":"text","value":"Finishing Up"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"ol","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"Add and commit your changes to Github. "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"Make sure to add and commit the new files you created."}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"Submit your repository to Gradescope."}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h2","properties":{"id":"grading"},"children":[{"type":"element","tagName":"a","properties":{"href":"#grading","ariaLabel":"grading permalink","className":["anchor"]},"children":[{"type":"element","tagName":"svg","properties":{"ariaHidden":"true","focusable":"false","height":"16","version":"1.1","viewBox":"0 0 16 16","width":"16"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","d":"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"},"children":[]}]}]},{"type":"text","value":"Grading"}]},{"type":"text","value":"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"},{"type":"element","tagName":"table","properties":{},"children":[{"type":"element","tagName":"thead","properties":{},"children":[{"type":"element","tagName":"tr","properties":{},"children":[{"type":"element","tagName":"th","properties":{},"children":[{"type":"text","value":"Points"}]},{"type":"element","tagName":"th","properties":{},"children":[{"type":"text","value":"Requirement"}]}]}]},{"type":"element","tagName":"tbody","properties":{},"children":[{"type":"element","tagName":"tr","properties":{},"children":[{"type":"element","tagName":"td","properties":{},"children":[{"type":"text","value":"✓/✗"}]},{"type":"element","tagName":"td","properties":{},"children":[{"type":"text","value":"Basic routes work"}]}]},{"type":"element","tagName":"tr","properties":{},"children":[{"type":"element","tagName":"td","properties":{},"children":[{"type":"text","value":"✓/✗"}]},{"type":"element","tagName":"td","properties":{},"children":[{"type":"text","value":"Validation tests pass"}]}]},{"type":"element","tagName":"tr","properties":{},"children":[{"type":"element","tagName":"td","properties":{},"children":[{"type":"text","value":"✓/✗"}]},{"type":"element","tagName":"td","properties":{},"children":[{"type":"text","value":"Passes all ESLint checks"}]}]}]}]}],"data":{"quirksMode":false}},"frontmatter":{"dueDate":"2019-11-13 5p","path":"/practicals/practical09","title":"CS 312 - Practical Nine","name":"Practical 9"},"parent":{"__typename":"File","id":"da114ce5-c5ff-5e61-8f98-e7a5c0be7ed4","name":"practical09-mongo","modifiedTime":"Nov 13 2019 20:33"}}},"pageContext":{"isCreatedByStatefulCreatePages":false}}}