End to End React with Prisma 2
Start at the beginning and work your way through this project. The code for each step as well as the finished project can be found in the Github repository.
15. Add queries, mutations and fragments
Objective: Add all the query and mutations files that our frontend will need.
Now that we know we have our backend in a good place, let's go ahead and create all of the queries and mutations that the backend will support. An important thing we will utilize to prevent code duplication is fragments. We actually have been using these for all of our testing, so hopefully they will look familiar. The essence of a fragment is that it will store all of the fields we want to return for a particular model type.
Let's look at this FeedTagFragment
. It is of type FeedTag
and we are saving it to the variable FEED_TAG_FRAGMENT
.
If we go down to FEED_FRAGMENT
we see that we can inject in the FEED_TAG_FRAGMENT
at the end of the fragment and use it within the FEED_FRAGMENT
by using the pattern ...FeedTagFragment
. This should kind of feel like the destructuring that we see with javascript and we are able to add all of these fragments together by using template strings template string example ${with-variables-injected-at-the-places-we-need-them}
.
utils/api/graphql/fragments.ts
ts
import { gql } from '@apollo/client'export const FEED_TAG_FRAGMENT = gql`fragment FeedTagFragment on FeedTag {idname}`export const BUNDLE_TAG_FRAGMENT = gql`fragment BundleTagFragment on BundleTag {idname}`export const AUTHOR_FRAGMENT = gql`fragment AuthorFragment on User {idauth0picturenickname}`export const LIKE_FRAGMENT = gql`fragment LikeFragment on Like {idname}`export const FEED_FRAGMENT = gql`fragment FeedFragment on Feed {idnameurllikes {...AuthorFragment}tags {...FeedTagFragment}author {...AuthorFragment}}${FEED_TAG_FRAGMENT}${AUTHOR_FRAGMENT}`export const BUNDLE_FRAGMENT = gql`fragment BundleFragment on Bundle {idnamedescriptiontags {...BundleTagFragment}author {...AuthorFragment}likes {...AuthorFragment}}${BUNDLE_TAG_FRAGMENT}${AUTHOR_FRAGMENT}`export const SAVED_ARTICLE_FRAGMENT = gql`fragment SavedArticleFragment on SavedArticle {idcontentsurlauthor {...AuthorFragment}feed {...FeedFragment}}${AUTHOR_FRAGMENT}${FEED_FRAGMENT}`
We go through all of the different models for these fragments and we export them all as fragments so we can use them in our queries and mutations. Let's tackle the queries first.
We can import all of these fragments that we just made at the top of our file. Let's take the bundles
query. You can see that we use the BundleFragment
to get all of our bundle fields, but when we want to get the nested feeds
we need to load that FeedFragment
inside the feeds
return object. The actual fragments we import as template string variables at the bottom of the query.
utils/api/graphql/queries.ts
ts
import { gql } from '@apollo/client'import {BUNDLE_FRAGMENT,BUNDLE_TAG_FRAGMENT,FEED_FRAGMENT,FEED_TAG_FRAGMENT,SAVED_ARTICLE_FRAGMENT,} from './fragments'export const BUNDLES_QUERY = gql`query {bundles {...BundleFragmentfeeds {...FeedFragment}}}${BUNDLE_FRAGMENT}${FEED_FRAGMENT}`export const FEEDS_QUERY = gql`query {feeds {...FeedFragmentbundles {...BundleFragment}}}${FEED_FRAGMENT}${BUNDLE_FRAGMENT}`export const FIND_FEEDS_QUERY = gql`query findFeedsQuery($data: FindFeedsInput) {findFeeds(data: $data) {...FeedFragmentbundles {...BundleFragment}}}${FEED_FRAGMENT}${BUNDLE_FRAGMENT}`export const FEED_QUERY = gql`query feedQuery($data: FeedInput) {feed(data: $data) {...FeedFragmentbundles {...BundleFragmentfeeds {...FeedFragment}}}}${FEED_FRAGMENT}${BUNDLE_FRAGMENT}`export const BUNDLE_QUERY = gql`query bundleQuery($data: BundleInput) {bundle(data: $data) {...BundleFragmentfeeds {...FeedFragmentbundles {...BundleFragment}}}}${FEED_FRAGMENT}${BUNDLE_FRAGMENT}`export const FIND_FEED_TAGS_QUERY = gql`query findFeedTagsQuery($data: FindFeedTagsInput) {findFeedTags(data: $data) {...FeedTagFragment}}${FEED_TAG_FRAGMENT}`export const FIND_BUNDLE_TAGS_QUERY = gql`query findBundleTagsQuery($data: FindBundleTagsInput) {findBundleTags(data: $data) {...BundleTagFragment}}${BUNDLE_TAG_FRAGMENT}`export const SAVED_ARTICLES_QUERY = gql`query savedArticlesQuery {savedArticles {...SavedArticleFragment}}${SAVED_ARTICLE_FRAGMENT}`export const SAVED_ARTICLE_QUERY = gql`query savedArticleQuery($data: SavedArticleInput) {savedArticle(data: $data) {...SavedArticleFragment}}${SAVED_ARTICLE_FRAGMENT}`
Finally, let's add the mutations. Nothing too surprising here
utils/api/graphql/mutations.ts
ts
import { gql } from '@apollo/client'import {BUNDLE_FRAGMENT,FEED_FRAGMENT,SAVED_ARTICLE_FRAGMENT,} from './fragments'export const LIKE_BUNDLE_MUTATION = gql`mutation likeBundleMutation($data: LikeBundleInput) {likeBundle(data: $data) {...BundleFragmentfeeds {...FeedFragment}}}${BUNDLE_FRAGMENT}${FEED_FRAGMENT}`export const LIKE_FEED_MUTATION = gql`mutation likeFeedMutation($data: LikeFeedInput) {likeFeed(data: $data) {...FeedFragmentbundles {...BundleFragment}}}${BUNDLE_FRAGMENT}${FEED_FRAGMENT}`export const CREATE_BUNDLE_MUTATION = gql`mutation createBundleMutation($data: BundleCreateInput) {createBundle(data: $data) {...BundleFragmentfeeds {...FeedFragmentbundles {...BundleFragment}}}}${FEED_FRAGMENT}${BUNDLE_FRAGMENT}`export const UPDATE_BUNDLE_MUTATION = gql`mutation updateBundleMutation($data: BundleUpdateInput) {updateBundle(data: $data) {...BundleFragmentfeeds {...FeedFragmentbundles {...BundleFragment}}}}${FEED_FRAGMENT}${BUNDLE_FRAGMENT}`export const CREATE_FEED_MUTATION = gql`mutation createFeedMutation($data: FeedCreateInput) {createFeed(data: $data) {...FeedFragmentbundles {...BundleFragmentfeeds {...FeedFragment}}}}${FEED_FRAGMENT}${BUNDLE_FRAGMENT}`export const UPDATE_FEED_MUTATION = gql`mutation updateFeedMutation($data: FeedUpdateInput) {updateFeed(data: $data) {...FeedFragmentbundles {...BundleFragmentfeeds {...FeedFragment}}}}${FEED_FRAGMENT}${BUNDLE_FRAGMENT}`export const CREATE_SAVED_ARTICLE_MUTATION = gql`mutation createSavedArticleMutation($data: SavedArticleCreateInput) {createSavedArticle(data: $data) {...SavedArticleFragment}}${SAVED_ARTICLE_FRAGMENT}`export const DELETE_BUNDLE_MUTATION = gql`mutation deleteBundleMutation($data: BundleInput) {deleteBundle(data: $data) {id}}`export const DELETE_FEED_MUTATION = gql`mutation deleteFeedMutation($data: FeedInput) {deleteFeed(data: $data) {id}}`export const DELETE_SAVED_ARTICLE_MUTATION = gql`mutation deleteSavedArticleMutation($data: DeleteSavedArticleInput) {deleteSavedArticle(data: $data) {idurl}}`