Coding

#5 GraphQL + MongoDB | Build a Complete App with GraphQL, Node.js, MongoDB and React.js

  • 00:00:01 hi and welcome back to this serious we
  • 00:00:05 started implementing our graph QL API we
  • 00:00:08 added the event type now it's time to
  • 00:00:12 also add a database behind the scenes so
  • 00:00:14 that our data is not just persisted in
  • 00:00:17 memory as I'm currently doing it which
  • 00:00:20 is of course not a great solution for a
  • 00:00:22 real application but that we instead
  • 00:00:25 persist our data in a real database now
  • 00:00:28 in this video I'll use MongoDB and we'll
  • 00:00:31 set it all up from scratch and
  • 00:00:33 manipulate our code such that we really
  • 00:00:36 use that database of course you could
  • 00:00:38 use any database though now let's
  • 00:00:41 implement it step by step
  • 00:00:45 as I mentioned I will be using MongoDB
  • 00:00:48 here – well as a database for this
  • 00:00:51 project and you could use a my sequel
  • 00:00:54 database you could use poast where as
  • 00:00:56 sequel you could use our new sequel
  • 00:00:58 databases so graph QL really doesn't
  • 00:01:01 care it works with any database because
  • 00:01:04 we will write the logic to interact with
  • 00:01:06 the database that's not built into graph
  • 00:01:08 QL as you will learn now I'll use
  • 00:01:11 MongoDB because I really like it it's
  • 00:01:13 really fast has good performance really
  • 00:01:17 flexible and if you want to learn more
  • 00:01:19 about MongoDB specifically I got a whole
  • 00:01:22 video and complete course on MongoDB and
  • 00:01:26 you'll find links to both in the video
  • 00:01:28 description and these are awesome
  • 00:01:29 resources to learn everything about
  • 00:01:31 MongoDB now here I will specifically use
  • 00:01:34 the cloud hosted database solution
  • 00:01:37 MongoDB offers MongoDB Atlas because I
  • 00:01:40 don't want to take care about
  • 00:01:41 administrating and setting up that
  • 00:01:43 database now for that you will need an
  • 00:01:46 account you can click on get MongoDB and
  • 00:01:48 on that page there you can choose cloud
  • 00:01:51 or that is actually selected by default
  • 00:01:53 and here you can sign up and you need no
  • 00:01:57 credit card for this you can start with
  • 00:01:59 this for free so you can sign up here
  • 00:02:02 and you will thereafter be prompted with
  • 00:02:05 a screen where you can set up your first
  • 00:02:08 MongoDB Atlas cluster and there you can
  • 00:02:10 choose all the free to your options and
  • 00:02:13 you will end up with a cluster and here
  • 00:02:15 I already am locked in that should look
  • 00:02:17 something like this so this is the
  • 00:02:19 screen you see after you configured and
  • 00:02:21 started your cluster with all the free
  • 00:02:24 tier options so where you don't pay
  • 00:02:26 anything and as I said you won't even
  • 00:02:28 need a credit card there for now once
  • 00:02:31 you have that cluster up and running we
  • 00:02:33 of course want to connect our
  • 00:02:35 application to it and to do that we need
  • 00:02:38 to do two things the first thing we need
  • 00:02:41 to do is manage our security settings
  • 00:02:44 here on the cluster such that our
  • 00:02:46 application is able to connect to the
  • 00:02:48 database because not everybody should be
  • 00:02:50 able to connect of course the second
  • 00:02:53 thing which is important is that we also
  • 00:02:57 use a
  • 00:02:58 cool a driver in our application so in
  • 00:03:02 our graph QL API which is able to query
  • 00:03:05 the database because we won't write
  • 00:03:08 queries ourself in a special language
  • 00:03:11 like sequel hazard instead we will use a
  • 00:03:14 tool that exposes methods we can execute
  • 00:03:16 against the database and I will walk you
  • 00:03:19 through all these steps now in this
  • 00:03:21 video let's start with the security
  • 00:03:23 settings here on the security tab and
  • 00:03:25 there you should make sure that you have
  • 00:03:27 at least one user who's either an admin
  • 00:03:30 which who is basically able to do
  • 00:03:32 everything or has read and write any
  • 00:03:34 database rights which means this user
  • 00:03:37 can read and write to any database you
  • 00:03:40 have on your cluster because on this
  • 00:03:42 cluster you can have multiple databases
  • 00:03:44 we will only use one but you can use a
  • 00:03:47 user with these rights now on such a
  • 00:03:50 user you want to set your own password
  • 00:03:52 or auto-generate one and I will quickly
  • 00:03:57 show it so that I can copy it because
  • 00:04:00 we'll needs that later and I will click
  • 00:04:03 update user to use that new
  • 00:04:05 auto-generated password and the other
  • 00:04:08 thing we need to do is that we not only
  • 00:04:09 know the user credentials but we also
  • 00:04:12 have to decide which servers can connect
  • 00:04:16 to that database cluster server here and
  • 00:04:19 there under IP whitelist I got a bunch
  • 00:04:23 of IP addresses here because I used this
  • 00:04:26 cluster for other projects too you
  • 00:04:28 probably have none of these addresses
  • 00:04:31 there what I want to do there is I want
  • 00:04:34 to add an IP address now I already added
  • 00:04:36 mine so I will quickly delete it here
  • 00:04:38 and thereafter I can click on add IP
  • 00:04:40 address and now choose add current IP
  • 00:04:43 address and this uses your local IP
  • 00:04:46 address so if your local machine where I
  • 00:04:50 will or we were we will do the
  • 00:04:51 development if you later deploy this API
  • 00:04:55 on to another server in the web you will
  • 00:04:57 need to use that IP address or that IP
  • 00:05:00 address range of that web server of
  • 00:05:03 course here I will confirm to add my
  • 00:05:05 local IP address and now I'm both
  • 00:05:08 allowed to connect from my low
  • 00:05:10 host:2 debt MongoDB server and I will
  • 00:05:13 have a user who has all the right access
  • 00:05:15 rights with that we can switch back to
  • 00:05:18 the application and now in here we need
  • 00:05:21 that other part that MongoDB driver that
  • 00:05:24 package that allows us to interact with
  • 00:05:26 MongoDB now here we could use the native
  • 00:05:28 MongoDB driver a package managed and
  • 00:05:31 maintained by the developers behind
  • 00:05:33 MongoDB but I will actually use mongoose
  • 00:05:37 mongoose is a third-party library you
  • 00:05:40 can install through npm which in the end
  • 00:05:42 builds up on that official MongoDB
  • 00:05:44 driver and adds extra convenience
  • 00:05:46 features and most importantly it allows
  • 00:05:50 us to work with models so it allows us
  • 00:05:52 to manage our data through javascript
  • 00:05:55 objects and for example when we then
  • 00:05:57 save such a object or execute certain
  • 00:06:00 methods on it then this automatically is
  • 00:06:03 translated to a query against the
  • 00:06:05 database which persists the day that
  • 00:06:08 there – or fetches it from there and
  • 00:06:10 therefore I will install this through
  • 00:06:13 NPM with NPM install – – save and then
  • 00:06:16 it's Mongoose like this now that
  • 00:06:21 installed this mongoose package and with
  • 00:06:24 that we can now restart our server here
  • 00:06:26 with NPM start but I will actually not
  • 00:06:29 do that instead here I will add a node
  • 00:06:32 maaan dot Jason file and this will
  • 00:06:35 automatically be used by that node Mon
  • 00:06:37 tool we use to start our server and
  • 00:06:39 there we can add some configuration for
  • 00:06:43 that node one tool and I want to pass in
  • 00:06:46 an environment variable which basically
  • 00:06:48 holds my sign in credentials for the
  • 00:06:52 database because I can then easily swap
  • 00:06:54 them by just editing them in that file
  • 00:06:56 if I later were to deploy that or to be
  • 00:06:59 precise we wouldn't even deploy that
  • 00:07:01 file so we can basically set up our
  • 00:07:03 credentials for our local development
  • 00:07:05 environment and later easily use our
  • 00:07:07 credentials when we deploy the app for
  • 00:07:10 that in here I need to add a ends key
  • 00:07:13 and in that end object I can now set up
  • 00:07:17 environment variables which will
  • 00:07:18 automatically be injected into the
  • 00:07:20 node.js application when it starts
  • 00:07:23 through node Mon which we can then
  • 00:07:24 consume inside of the node application
  • 00:07:27 there I will add a Mongo user and here
  • 00:07:31 my user name was Maximilian of course
  • 00:07:33 you probably have a different user name
  • 00:07:35 and I have Mongo password and that is
  • 00:07:39 that password I generated and copied
  • 00:07:43 with that edited this will automatically
  • 00:07:47 be consumed and now in App Jazz we want
  • 00:07:49 to connect to Mongoose
  • 00:07:51 for that I'll first of all a to MongoDB
  • 00:07:54 fruit Mongoose for that I will first of
  • 00:07:57 all import with require import Mongoose
  • 00:08:00 here and now we can use Mongoose to
  • 00:08:03 establish such a connection I'll do that
  • 00:08:05 towards the end of this files file here
  • 00:08:08 there I will use Mongoose and this has a
  • 00:08:11 connect method now disconnect method
  • 00:08:13 first of all needs a connection string
  • 00:08:15 which basically is the address of our
  • 00:08:17 database cluster or a server and we can
  • 00:08:20 get that string if you go back to the
  • 00:08:22 cluster to the overview and click on
  • 00:08:23 connect there and this will open a modal
  • 00:08:28 there we can choose connect your
  • 00:08:29 application and then choose that which
  • 00:08:32 requires MongoDB 3.6 or higher this SRV
  • 00:08:36 string copy that string and add this
  • 00:08:40 here and now we'll actually use
  • 00:08:43 backticks here to create a template
  • 00:08:45 literal because this will allow me to
  • 00:08:47 now dynamically change my username and
  • 00:08:51 my password here so or for the username
  • 00:08:54 I will use and now we can access this at
  • 00:08:56 this environment variable as we always
  • 00:08:58 do it in nodejs with process dot n dot
  • 00:09:01 and then here I have Mongo user so does
  • 00:09:05 first environment variable we added a
  • 00:09:07 second ago
  • 00:09:07 and I'll also replace the password here
  • 00:09:10 of course with process and Mongo
  • 00:09:14 password okay and now we construct this
  • 00:09:19 connection string to connect method that
  • 00:09:22 actually gives us a promise and here we
  • 00:09:25 could fail so I will just log any errors
  • 00:09:27 we get for example you could fail if our
  • 00:09:30 cluster is down if the credentials are
  • 00:09:32 incorrect if our local network
  • 00:09:33 connection kind of is broken
  • 00:09:36 we succeed and in this case in the van
  • 00:09:39 block in this case that we succeeded I
  • 00:09:42 want to start up my server now you could
  • 00:09:44 also have a set of where you always
  • 00:09:45 start your server no matter if you
  • 00:09:47 connected successfully or not and you
  • 00:09:49 then have some logic to retry the
  • 00:09:51 connection I will take this route here
  • 00:09:53 and now with that let's run NPM start to
  • 00:09:57 bring up that node one server and try
  • 00:10:00 connecting to MongoDB and this succeeded
  • 00:10:03 we can't ignore that deprecation warning
  • 00:10:05 here we got no error so now I'm
  • 00:10:08 successfully connected to MongoDB to my
  • 00:10:10 cluster to my database and now it's time
  • 00:10:13 to actually start adding some logic to
  • 00:10:16 interact with that database because
  • 00:10:19 that's far in my resolver here in this
  • 00:10:22 file create event for example I only
  • 00:10:25 store this in my events array here and
  • 00:10:29 that is just in memory now I want to use
  • 00:10:31 MongoDB and I want to use that strongly
  • 00:10:34 typed modeling feature mongoose gives me
  • 00:10:38 therefore i'll add a new folder here
  • 00:10:40 which i'll name models and in there I
  • 00:10:42 will add an event dot JS file and this
  • 00:10:45 will be a model a JavaScript model
  • 00:10:48 created with that mongoose package
  • 00:10:50 because that package is all about using
  • 00:10:52 models to manage data so that we can
  • 00:10:54 easily implement a model of view
  • 00:10:56 controller or in our case a model
  • 00:10:58 controller endpoint approach for this I
  • 00:11:03 will also import mongoose in here in
  • 00:11:06 this file with the same syntax we used
  • 00:11:08 in app j s and then i need a specific
  • 00:11:10 feature from the mongoose package which
  • 00:11:13 is called schema and i will add a
  • 00:11:15 capital ass here because whatever i'm
  • 00:11:18 going to access now will actually be a
  • 00:11:20 constructor function and I get that from
  • 00:11:23 Mongoose there is this schema property
  • 00:11:26 and again this points at a constructor
  • 00:11:28 function which I can use to generate new
  • 00:11:31 schema objects schemas are the first
  • 00:11:34 important building block added by
  • 00:11:36 Mongoose because we can now create an
  • 00:11:38 event the schema here and you can name
  • 00:11:41 this however you want of course by
  • 00:11:43 instantiating this with the new keyword
  • 00:11:45 since it is a constructor function we
  • 00:11:47 can create a new object with it with the
  • 00:11:49 new keyword
  • 00:11:50 and then we pass a JavaScript object
  • 00:11:52 here to the constructor function where
  • 00:11:55 we define the structure and this allows
  • 00:11:56 us to define the structure of an event
  • 00:11:59 object which we can then reuse
  • 00:12:01 throughout our entire app and where we
  • 00:12:04 then are guaranteed that every event
  • 00:12:06 object will look exactly like this now
  • 00:12:09 how should an event look like well if we
  • 00:12:12 have a look at our app J's file then we
  • 00:12:16 see that an event here in our graph QL
  • 00:12:18 API has an ID and this will actually be
  • 00:12:21 added automatically by MongoDB among us
  • 00:12:24 so we don't need to add that then we
  • 00:12:26 will have a title a description a price
  • 00:12:28 and a date and later I will also add
  • 00:12:31 more once you add users and we want to
  • 00:12:34 connect an event to a user and so on but
  • 00:12:36 for now we can go with these four fields
  • 00:12:39 now back in our event model in that
  • 00:12:42 schema here we simply add a title
  • 00:12:44 property here in that object we pass
  • 00:12:47 through the schema constructor and now I
  • 00:12:49 could add string here to define that
  • 00:12:51 this will actually be a string and
  • 00:12:53 Mongoose or Longwood EP then we'll
  • 00:12:55 respect this and we'll store the data as
  • 00:12:57 such and will yell at us if we try to
  • 00:13:00 use different data but I will actually
  • 00:13:02 pass an object here because I can then
  • 00:13:04 configure this in greater detail and
  • 00:13:06 there we have a type property which I
  • 00:13:08 set to string to make clear yes the type
  • 00:13:11 of the title property will be string but
  • 00:13:13 it will also add the required property
  • 00:13:15 to make clear it's not just a string it
  • 00:13:18 also is required so it must not be null
  • 00:13:20 and that of course also fits our graph
  • 00:13:24 QL schema which is otherwise not related
  • 00:13:27 to the MongoDB schema by the way there I
  • 00:13:29 also have a non nullable type because I
  • 00:13:32 added that exclamation mark and of
  • 00:13:34 course we kind of want to keep our
  • 00:13:36 MongoDB schema which affects what we
  • 00:13:38 save in the database and our graph QL
  • 00:13:41 schema which affects what we work with
  • 00:13:43 and what we return we want to keep these
  • 00:13:45 two in sync right because we say in
  • 00:13:47 graph QL this will never be null and we
  • 00:13:50 do allow null values in the data we
  • 00:13:53 store it in the database then we have a
  • 00:13:55 mismatch which will ultimately lead to
  • 00:13:57 problems so here I have my title I will
  • 00:14:01 now also add my description here
  • 00:14:03 and on this description I will also set
  • 00:14:07 the type to string because the
  • 00:14:09 description will be a text and this will
  • 00:14:11 also be required them there must not be
  • 00:14:13 an event without a description in Maya
  • 00:14:16 of course you could tweak this to your
  • 00:14:18 likings I will also add a price here and
  • 00:14:22 dad will now actually be a number there
  • 00:14:25 is no float in JavaScript there is just
  • 00:14:28 a number
  • 00:14:28 integers and floats are both combined
  • 00:14:31 and that number type and this will also
  • 00:14:33 be required now here I will also have a
  • 00:14:37 date then and the type here will be date
  • 00:14:40 unlike graph QL where we had to use
  • 00:14:43 string we do have the date type in
  • 00:14:46 MongoDB so we can use it here and of
  • 00:14:49 course will be our duty to convert this
  • 00:14:51 when we pass it back to graph QL to the
  • 00:14:55 front end and to the database and this
  • 00:14:57 will also be required okay so this is my
  • 00:15:00 schema for now
  • 00:15:02 now the schema alone doesn't help us we
  • 00:15:04 now need to create a so-called model
  • 00:15:06 based on a schema the schema kind of us
  • 00:15:09 like our plan you could say the model
  • 00:15:12 then is the blueprint which incorporates
  • 00:15:15 that plan which we can then use to
  • 00:15:17 create objects with which we actually
  • 00:15:19 work in our application we create such a
  • 00:15:22 model also with Mongoose by calling the
  • 00:15:25 model method and this takes now at least
  • 00:15:28 two arguments the first argument is that
  • 00:15:32 the name of the model and here I want to
  • 00:15:35 name this event and this has to be a
  • 00:15:37 string this will affect
  • 00:15:40 collection in which just gets stored in
  • 00:15:43 our MongoDB database and it will also
  • 00:15:45 affect other things by which you can
  • 00:15:46 access this and so on
  • 00:15:48 now the second argument here is a
  • 00:15:50 pointer at the schema we want to use for
  • 00:15:52 that model and here I wanted to use my
  • 00:15:54 event schema of course now this creates
  • 00:15:58 a model but in this file it's not that
  • 00:16:01 useful to us we want to use it in our
  • 00:16:03 files and therefore I will export it
  • 00:16:05 with the notes as export syntax which is
  • 00:16:08 module exports equals this model and now
  • 00:16:12 we can import that file into our files
  • 00:16:14 and consume our model there now
  • 00:16:17 with that model setup we made a huge
  • 00:16:19 step forward now in app says I want to
  • 00:16:21 change one everything here I also need
  • 00:16:26 to define in which database this gets
  • 00:16:28 stored because we connect to a cluster
  • 00:16:30 here and actually also to a database in
  • 00:16:32 a cluster this is this part here after
  • 00:16:34 that slash and if that database doesn't
  • 00:16:37 exist yet it will be created on the fly
  • 00:16:39 the same is by the way true with mom
  • 00:16:41 would you be for all collections and so
  • 00:16:43 on it's all created on the fly if it
  • 00:16:45 doesn't exist now I don't want to use
  • 00:16:47 test as a database name instead I'll go
  • 00:16:50 back to my node montt file and in there
  • 00:16:54 I will add my MongoDB field and I will
  • 00:16:58 name this he when's react death you can
  • 00:17:04 use any name you want this will be that
  • 00:17:06 the name of the database which will be
  • 00:17:08 created automatically and now in App
  • 00:17:10 jeaious I can replace this with some
  • 00:17:13 dynamically injected value which is
  • 00:17:15 process dot n dot MongoDB the name of
  • 00:17:19 that environment variable I just added
  • 00:17:21 now if I save this it will restart and
  • 00:17:23 connect to that database and now any
  • 00:17:26 data we save will get saved in that
  • 00:17:28 database
  • 00:17:28 so there is a lot of work already now
  • 00:17:32 let's finally tweak our code such that
  • 00:17:34 we actually do save our events in the
  • 00:17:37 database and that we do fetch the events
  • 00:17:40 from there as well for that in app Jess
  • 00:17:44 let's import our own model I'll name
  • 00:17:52 this event with a capital e because the
  • 00:17:54 Mongoose model created by that model
  • 00:17:57 method here actually will also be a
  • 00:17:59 constructor function we can use to build
  • 00:18:01 JavaScript objects based on our model we
  • 00:18:04 defined here I do import it by simply
  • 00:18:08 importing from that models folder and
  • 00:18:10 there that event file we created and now
  • 00:18:12 we can use that event constructor here
  • 00:18:14 to create a new event object that we
  • 00:18:17 want to save to the database so
  • 00:18:20 previously we created this like this
  • 00:18:23 with the object literal way here now I
  • 00:18:28 will create my event by calling new
  • 00:18:31 event using that event constructor
  • 00:18:33 generated by Mongoose model and there we
  • 00:18:36 now pass a JavaScript object where we
  • 00:18:38 pass fields or values for all the fields
  • 00:18:42 we defined in our schema so in this case
  • 00:18:45 in case you forgot it you can quickly
  • 00:18:47 check we got a title description price
  • 00:18:50 and date field so basically what I set
  • 00:18:53 before already so here we can set the
  • 00:18:55 title and this now should be a string
  • 00:18:57 and basically I can copy that right
  • 00:19:00 because that is exactly what I wanted to
  • 00:19:03 pass or store before it still is what I
  • 00:19:06 want to store one exception is to date
  • 00:19:09 here the date now can be a real date
  • 00:19:13 when we save in the database I still
  • 00:19:15 will get it as a string but then I
  • 00:19:17 expect this to be a string that can be
  • 00:19:19 parsed into a date object so I can use
  • 00:19:22 the built in date constructor and parse
  • 00:19:25 that incoming string into a javascript
  • 00:19:28 date object which is then passed on and
  • 00:19:30 which will be stored in the database and
  • 00:19:33 of course MongoDB then all the stores is
  • 00:19:35 in a slightly different format but this
  • 00:19:36 is all basically trans transformable
  • 00:19:40 between JavaScript and MongoDB and the
  • 00:19:43 other way around I then don't want you
  • 00:19:46 push my event on to some event array or
  • 00:19:49 events array I will actually get rid of
  • 00:19:51 that array here we don't need it anymore
  • 00:19:52 instead here on this event object since
  • 00:19:56 it is based on a mongoose model it's not
  • 00:19:58 a normal plain vanilla JavaScript object
  • 00:20:00 I can call a couple of methods on that
  • 00:20:02 and one method is the save method this
  • 00:20:05 is provided by the Mongoose package and
  • 00:20:07 save will actually hit the database and
  • 00:20:11 write our data as we define it here into
  • 00:20:14 the database so here I'm saving this and
  • 00:20:19 then I can call then and catch there
  • 00:20:23 after because this actually returns not
  • 00:20:26 a real promise but a promise like object
  • 00:20:28 dead for our purposes works like a
  • 00:20:31 promise and then I either got an error
  • 00:20:34 which I can catch and where I can
  • 00:20:37 console.log the error or where I have
  • 00:20:41 some result of that operation
  • 00:20:44 and I can console Locke that result here
  • 00:20:46 – now keep in mind we also need to
  • 00:20:49 return an event object here due to our
  • 00:20:52 graph QL configuration which basically
  • 00:20:54 tells us when we call create event we
  • 00:20:57 return an event and I can already tell
  • 00:21:01 you that result will basically be an
  • 00:21:04 event object so I can return result here
  • 00:21:07 though to be very precise this is like
  • 00:21:11 enriched document or an enriched object
  • 00:21:16 with a lot of metadata we can return a
  • 00:21:18 new javascript object here and use the
  • 00:21:21 spread operator to get result dot
  • 00:21:23 underscore doc which is property
  • 00:21:27 provided by Mongoose which gives us all
  • 00:21:29 the core properties made that make up
  • 00:21:32 our document our object or event object
  • 00:21:35 and leave out all the metadata and then
  • 00:21:38 we return this now if we have an error I
  • 00:21:42 of course all don't want to return
  • 00:21:43 something and there I basically want you
  • 00:21:47 just throw that error again so that
  • 00:21:49 graph QL Express graph QL can handle
  • 00:21:52 that and can return us an error this is
  • 00:21:57 our create event resolver here now one
  • 00:22:01 important thing is you should return
  • 00:22:04 this here so that graph QL Express graph
  • 00:22:07 QL actually knows that this resolver
  • 00:22:09 executes an async operation at the end
  • 00:22:12 and it will wait for this to complete
  • 00:22:13 otherwise it would complete instantly
  • 00:22:16 and would therefore not get a valid
  • 00:22:17 result so we need to return our promise
  • 00:22:20 here then we can use the rest of the
  • 00:22:23 code get rid of our old event definition
  • 00:22:25 here or object creation to be precise
  • 00:22:29 with that we should be good to go to
  • 00:22:31 restore an event at the database now
  • 00:22:34 let's give this a try on our localhost /
  • 00:22:39 graph QL URL where we can run our graph
  • 00:22:43 QL queries and play around with them and
  • 00:22:44 there we want to execute a mutation
  • 00:22:47 against create event where we need to
  • 00:22:50 pass an event input and there we have a
  • 00:22:52 title a test we have a description this
  • 00:22:56 is a test
  • 00:22:57 we got a price which should be a float
  • 00:23:00 so let's use $9.99 for example and last
  • 00:23:04 but not least we got that date and here
  • 00:23:06 I will open up my developer tools really
  • 00:23:08 quick because here I still need to pass
  • 00:23:10 a string and I can generate one with the
  • 00:23:13 help of the developer tools here by just
  • 00:23:15 calling new date Qi so string this will
  • 00:23:18 give me today as a string I will copy
  • 00:23:21 that close to developer tools and pass
  • 00:23:24 that string here and then we should get
  • 00:23:27 back an event so of course here I will
  • 00:23:31 actually then
  • 00:23:32 well for example fetch the title
  • 00:23:35 let me prettify that and execute this
  • 00:23:38 career and this doesn't look too bad I
  • 00:23:40 get back a title now let's look into our
  • 00:23:43 MongoDB database and you should be able
  • 00:23:45 to do that here from inside that mom
  • 00:23:47 would be class review by clicking on
  • 00:23:49 collections if you don't have that
  • 00:23:51 button there you can search for a
  • 00:23:53 MongoDB comm-pass which is a tool
  • 00:23:56 provided by the moon would be company
  • 00:23:58 that also allows you to connect to your
  • 00:24:00 database and then inspect your database
  • 00:24:02 so you can download that it's free to
  • 00:24:05 use and there you can visualize your
  • 00:24:07 data in the database and look into it
  • 00:24:09 but here I got that integrated into my
  • 00:24:12 well view here and if I click on
  • 00:24:15 collections it will load all my
  • 00:24:18 databases and all my collections and I
  • 00:24:20 actually got more than one database you
  • 00:24:22 probably only have the one we are
  • 00:24:24 working with I got a couple of databases
  • 00:24:28 I'm looking for my on the find databases
  • 00:24:32 looks like so seems like I made a
  • 00:24:36 mistake here process and MongoDB I
  • 00:24:41 probably should have restarted that now
  • 00:24:45 that server here because I changed node
  • 00:24:48 one Jason with it running didn't pick up
  • 00:24:50 the new configuration makes sense now on
  • 00:24:53 the finest database which was created
  • 00:24:55 here due to my mistake we'll fix this in
  • 00:24:57 a second but there we do have that
  • 00:24:58 events collection and if we look into
  • 00:25:00 that there you should actually find your
  • 00:25:05 event which was created a second ago
  • 00:25:08 this is the date I just generated the
  • 00:25:10 surprise
  • 00:25:11 so this all worked please note that the
  • 00:25:14 ID was auto-generated it's that strange
  • 00:25:16 object ID type which is a special data
  • 00:25:20 type provided by MongoDB it's a unique
  • 00:25:23 string that is also taking into account
  • 00:25:26 the current timestamp with that we got
  • 00:25:29 it all working now I'll quickly just
  • 00:25:31 stop my server and restart and I'll then
  • 00:25:35 execute that same query again and now I
  • 00:25:38 will refresh here and now I should have
  • 00:25:40 that correctly named database there it
  • 00:25:42 is events reacts death my mistake I did
  • 00:25:46 restart after changing the node one
  • 00:25:47 conflict but the main important or the
  • 00:25:50 most important thing is we are able to
  • 00:25:52 save the data now saving data is of
  • 00:25:55 course one nice thing we also want to be
  • 00:25:58 able to retrieve the data right so let's
  • 00:26:00 go to our other resolver where we
  • 00:26:02 returned the events and it's not that
  • 00:26:05 simple anymore instead of just returning
  • 00:26:07 some events array which doesn't exist
  • 00:26:10 anymore because I deleted it we can use
  • 00:26:12 the event constructor like this so
  • 00:26:14 without new and there we actually have a
  • 00:26:17 couple of static methods so methods we
  • 00:26:20 can call on the event constructor
  • 00:26:22 function without actually creating an
  • 00:26:25 object based on it and one method we can
  • 00:26:29 call here is find find allows us to well
  • 00:26:33 as the name suggests find documents in
  • 00:26:35 that collection so find event documents
  • 00:26:38 we could pass a filter so an object
  • 00:26:41 where we say find objects where the
  • 00:26:43 title is a test for example you can
  • 00:26:46 learn more about filtering in my MongoDB
  • 00:26:48 course we'll probably also do it
  • 00:26:50 throughout this series but if we don't
  • 00:26:52 pass anything here it will give us all
  • 00:26:54 the entries in that collection and that
  • 00:26:57 is exactly what I want and then again we
  • 00:27:00 have this promise like API where we can
  • 00:27:04 get an error which I want to basically
  • 00:27:07 throw or where we get the result in my
  • 00:27:12 case my events documents and then I want
  • 00:27:15 to return these of course because our
  • 00:27:18 events endpoint here actually should
  • 00:27:20 return an array of events right
  • 00:27:23 therefore in here
  • 00:27:25 we could now say return events but just
  • 00:27:28 as before the events a day that we get
  • 00:27:31 back by Mongoose actually has some
  • 00:27:33 metadata attached to it so I will use
  • 00:27:36 the map operator here and I will
  • 00:27:38 transform every event in that array that
  • 00:27:41 is retrieve by MongoDB by into a new
  • 00:27:45 object so I will return a new object for
  • 00:27:48 every element in events and there I will
  • 00:27:50 use the spread operator and use
  • 00:27:52 everything from event doc like this and
  • 00:27:55 with that I leave out all the metadata
  • 00:27:58 and then I can here I'll return this
  • 00:28:02 whole operation so that graph QL Express
  • 00:28:06 graph QL again knows we're doing
  • 00:28:08 something asynchronous here wait for it
  • 00:28:11 to finish and don't try to return
  • 00:28:13 something too early
  • 00:28:15 okay now let's save that let's go back
  • 00:28:18 to graphical and let's run a query now
  • 00:28:22 against events and there whoops
  • 00:28:25 hit enter too early there let's for
  • 00:28:28 example fetch the title and this works
  • 00:28:31 and now let's all to fetch the ID and
  • 00:28:33 this will now actually give you an error
  • 00:28:36 and that's good because now we also see
  • 00:28:38 how an error looks like we get this
  • 00:28:40 errors object and there I get the error
  • 00:28:42 that the ID cannot represent this value
  • 00:28:45 now the problem here is that special ID
  • 00:28:49 data type MongoDB uses this object ID
  • 00:28:53 data type and this is something which is
  • 00:28:55 not natively translated into a string or
  • 00:28:59 which isn't understood by graph QL so we
  • 00:29:02 need to translate it into a string now
  • 00:29:04 how do we do that well when we return
  • 00:29:06 our events here I do pull out all the
  • 00:29:10 data in this dark property which
  • 00:29:13 Mongoose adds which is all my core event
  • 00:29:15 data and now I just can overwrite
  • 00:29:18 underscore ID by adding it again
  • 00:29:20 thereafter and this will replace the
  • 00:29:22 first underscore ID which is pulled out
  • 00:29:24 of the document and there I will call
  • 00:29:27 event dark underscore ID Q string to be
  • 00:29:33 very clear what I want to do here so I
  • 00:29:35 will access this document with all its
  • 00:29:37 data there
  • 00:29:38 will access the ID and it will call to
  • 00:29:41 string which is a method which is
  • 00:29:42 available which will convert this to a
  • 00:29:44 normal string that is then understood by
  • 00:29:47 graph QL if I save that I can execute
  • 00:29:51 that exact same query which failed a
  • 00:29:52 second ago and it now succeeds and here
  • 00:29:55 is the string idea obviously this is not
  • 00:29:58 just a problem when we get all events
  • 00:30:00 but also when I return to generated
  • 00:30:03 event there I also want to override the
  • 00:30:06 ID with my result doc ID q string now
  • 00:30:12 there is a shortcut by the way which is
  • 00:30:15 worth noting mangu is also gives us
  • 00:30:18 another property we can access event ID
  • 00:30:23 like this this is a virtual getter
  • 00:30:27 provided by Mongoose and you see it now
  • 00:30:30 still works
  • 00:30:31 this basically abstracts all this logic
  • 00:30:34 away so we can use event ID and MongoDB
  • 00:30:37 or Mongoose to be precise Mongoose will
  • 00:30:39 actually access the native ID and
  • 00:30:42 translate this into a string here please
  • 00:30:44 note that I also don't have an
  • 00:30:46 underscore here because this really is a
  • 00:30:47 different property this is a property
  • 00:30:50 added by Mongoose to let us access the
  • 00:30:53 ID in an easy way we could use it down
  • 00:30:55 there too I believe two or above methods
  • 00:30:59 here or both approaches so that you see
  • 00:31:01 what's happening behind the scenes and
  • 00:31:04 now with that we are able to query our
  • 00:31:07 events let's now also add another event
  • 00:31:09 again create event with our event input
  • 00:31:13 where we have the title just another
  • 00:31:17 event the description whoops this is
  • 00:31:20 another event where I then also have the
  • 00:31:24 price let's say 100 29.99 and where I
  • 00:31:28 also have to date and here to keep it
  • 00:31:31 simple I will just use that same date
  • 00:31:32 from before again and then let's say I
  • 00:31:35 want to get that ID back and I want to
  • 00:31:37 get that title back and if I hit enter
  • 00:31:39 this works proving the fact that we fix
  • 00:31:42 that ID error for the mutation to you
  • 00:31:44 and if I try that query for all my
  • 00:31:47 events again then you will see here I
  • 00:31:50 can for example fetch two titles and
  • 00:31:51 descriptions of
  • 00:31:52 events and I get more than one now I got
  • 00:31:55 two events awesome now this was quite a
  • 00:31:58 long video but we did at MongoDB here we
  • 00:32:01 now work with real data and we store it
  • 00:32:04 in a real database in the next video
  • 00:32:06 let's refine our API
  • 00:32:08 let's restructure it a bit let's work on
  • 00:32:11 that schema and let's also make sure
  • 00:32:12 that throughout the next videos we also
  • 00:32:16 are able to add users book events and so
  • 00:32:19 on