visit
Node relationships in the graph
The app contains routes for viewing the home page, viewing a single subreadit, viewing a specific post, and viewing an individual user. Here we see the home page:Readit home page
If you’d like to follow along at home or try this out on your machine, all of the . You can also .Configuring a new Dgraph Cloud backend
Since this is a demo app, we can choose the Starter option for the product type. Production apps should use a higher tier with a shared or dedicated instance though. I left my region as “us-west-2”, since that’s the region closest to me. I used “reddit-clone” for the name, but feel free to use whatever you like.After filling out all the options, we can click “Launch” to spin up the new backend. Once the backend has been created, we’ll see an overview page with the new backend API endpoint:New backend API endpoint
Now it’s time to build a schema. This schema declares the various types of data that we’ll be working with in our app and storing in our database. We can either enter our schema info directly in the Schema Editor, or, for a more interactive experience, use UI Mode. Let’s use UI Mode to create our schema. The GUI helps us configure our types, their fields, and even the relationship between various types and fields.Creating a schema in UI Mode
After creating the schema, we can click the “Deploy” button to make it official. If we now look at the Schema Editor view, we’ll see the resulting GraphQL snippet:As you can see, each field has an associated type. For instance, the
Comment
type we created has an id
field that contains a unique identifier generated by Dgraph Cloud. It has a commentContent
field which contains the string text entered by the user. It has a voteCount
field which is an integer representing the number of votes the comment has received. Finally, the user
field references the user that wrote the comment, and the post
field references the post on which the comment was made.The relationship between the comment and the user is designated by the
@hasInverse
directive which tells Dgraph Cloud that the Comment
type is linked to the User
type by the comments
field on the User
type. The same is true for the relationship between the comment and the post.You’ll also notice that a few of our fields include the
@search
directive. This allows us to filter our queries by these searchable fields. For instance, we can find a specific subreddit by filtering our query results by a specific string of text for the name
field. The same is true when filtering user results by their userName
field.The next step is to populate the database with some seed data, which we can do using the API Explorer. We won’t go through all the mutations necessary to populate the data in this article, but you can . These snippets are used to create the subreadits, users, posts, and comments.For example, here’s what I used to create a few subreadits:yarn create react-app reddit-clone
cd reddit-clone
Next, we’ll install
react-router-dom
so that we can do client-side routing in the single page app with React Router:yarn add react-router-dom
Using React Router, we can create routes for each of our pages: home, subreadit, post, and user. Below is the
App
component with each of its routes:Then, we’ll install a couple of packages for , which is a JavaScript state management library for working with GraphQL. While it’s possible to make requests to a GraphQL API endpoint directly using something like the
fetch
API, Apollo Client makes this process even simpler.yarn add @apollo/client graphql
(You’ll note that we’ve installed the
graphql
package as well as the @apollo/client
package, even though we never directly use the graphql
package in our code. This is because graphql
is a peerDependency
of @apollo/client
and is used internally to facilitate working with GraphQL in JavaScript.)Now that we have Apollo Client installed, we can easily query data from the GraphQL backend and consume it in our React components. We can first create the Apollo client like so:And then we can wrap our main
App
component in the ApolloProvider
in the index.js
file:Readit home page
We can query our endpoint for that information and then use Apollo to declaratively handle the
loading
, error
, and response
data states. The code for the HomePage
component is reproduced in full below:Note how when retrieving the user info, we don’t need to fetch all of the user’s posts and comments. The only thing we’re interested in for the home page is how many posts and how many comments each user has. We can use the
count
field from postsAggregate
and commentsAggregate
to find the relevant numbers.Readit subreadit page for the 1984 subreadit
On this page, we need the data for the subreadit name and description, just like we did on the home page. We now also need to fetch all of the posts that are part of this subreadit. For each post, we need the post title, the number of votes and comments, and the username of the user who posted it. We don’t need the actual comments yet though since they’re not displayed on this page.Here’s the code for the
SubreaditPage
component:Readit post page for Oscar’s post
Here we need all the same post data that we did on the subreadit page, but now we also need to know the subreadit it was posted on, and we need all of the comments on the post. For each comment, we need to know the username for the user who posted it, what the actual comment content was, and how many votes it has.The code for the
PostPage
looks like this:Readit user page for Oscar Martinez
This page should show the user’s username, bio, number of posts, and number of comments. We also need all of their posts and all of their comments. On each post, we need to know the subreadit it was posted on, the post title, as well as the number of votes and comments. For each comment, we need to know which post it was a comment on, what the comment content was, and the number of votes it’s received.The code for the
UserPage
is below:This page is by far the most complex, as we need to query more than just summary data or aggregate count data.Also published .