{"id":27370226,"url":"https://github.com/datastaxdevs/workshop-intro-to-graphql","last_synced_at":"2025-07-08T10:11:00.099Z","repository":{"id":37917111,"uuid":"404180713","full_name":"datastaxdevs/workshop-intro-to-graphql","owner":"datastaxdevs","description":"Learn the basics of GraphQL. Plenty of hands-on experience covering: a React client interacting with Astra DB using the Netlify stack; usage of playgrounds and tooling; running your own Java GraphQL backend based on the Netflix DGS framework.","archived":false,"fork":false,"pushed_at":"2023-02-09T16:24:19.000Z","size":56512,"stargazers_count":80,"open_issues_count":93,"forks_count":44,"subscribers_count":8,"default_branch":"main","last_synced_at":"2025-04-13T08:57:11.448Z","etag":null,"topics":["cassandra","dgs-framework","gitpod","graphql","nosql","workshop"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/datastaxdevs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2021-09-08T02:06:34.000Z","updated_at":"2024-11-18T21:09:47.000Z","dependencies_parsed_at":"2023-02-16T10:01:53.310Z","dependency_job_id":null,"html_url":"https://github.com/datastaxdevs/workshop-intro-to-graphql","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/datastaxdevs/workshop-intro-to-graphql","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/datastaxdevs%2Fworkshop-intro-to-graphql","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/datastaxdevs%2Fworkshop-intro-to-graphql/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/datastaxdevs%2Fworkshop-intro-to-graphql/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/datastaxdevs%2Fworkshop-intro-to-graphql/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/datastaxdevs","download_url":"https://codeload.github.com/datastaxdevs/workshop-intro-to-graphql/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/datastaxdevs%2Fworkshop-intro-to-graphql/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264248024,"owners_count":23579059,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cassandra","dgs-framework","gitpod","graphql","nosql","workshop"],"created_at":"2025-04-13T08:48:23.332Z","updated_at":"2025-07-08T10:11:00.072Z","avatar_url":"https://github.com/datastaxdevs.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🎓 Introduction to GraphQL + React + Java + Astra DB\n\n[![Gitpod ready-to-code](https://img.shields.io/badge/Gitpod-ready--to--code-blue?logo=gitpod)](https://gitpod.io/from-referrer/)\n[![License Apache2](https://img.shields.io/hexpm/l/plug.svg)](http://www.apache.org/licenses/LICENSE-2.0)\n[![Discord](https://img.shields.io/discord/685554030159593522)](https://discord.com/widget?id=685554030159593522\u0026theme=dark)\n\n*50 minutes, Beginner/Intermediate, [Start Building](#1-login-or-register-to-astradb-and-create-database)*\n\nBoth a simple **graphQL** enabled **ReactJS** app built using [**create-react-app**](https://create-react-app.dev/) AND a simple **Java** backend **graphQL** service built with [**Spring Initializr**](https://start.spring.io/) and using [**The Netflix DGS framework**](https://netflix.github.io/dgs/getting-started/) PLUS **Astra DB** hooked up and ready to rock! :heart_eyes_cat:\n\nThis is a companion to our [Netflix Clone using Astra DB and GraphQL](https://github.com/datastaxdevs/appdev-week3-graphql) workshop and is essentially a \"prologue\" to that content. Once complete, feel free to to go deploy a Netflix clone using what you learned here.\n\nFinally, this content uses **React/JS** concepts. If you are not familiar with those or need a refresher, [take a look HERE](https://github.com/datastaxdevs/react-basics) to get up to date.\n\nThe materials have been built by the DataStax developer advocates team.\n\n![GraphQL Logo](./tutorial/images/graphQL_logo.png)\n\n## 🎯 Objectives\n* An overview of what GraphQL is and what makes it cool\n* What differs between GraphQL and other APIs (such as REST), including their pros/cons\n* Hands-on examples of GraphQL queries and mutations\n* How to build GraphQL APIs for mobile and web applications\n* Setting up your Astra DB to store application data via GraphQL\n\n## ℹ️ Frequently asked questions ℹ️\n\n\u003cp/\u003e\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003e 1️⃣ Can I run the code for this workshop on my local computer instead of using Gitpod?\u003c/b\u003e\u003c/summary\u003e\n\u003chr\u003e\n\u003cp\u003eThere is nothing preventing you from running the workshop on your own machine. If you do so, you will need the following:\n\u003col\u003e\n  \u003cli\u003e\u003ca href=\"https://www.whitesourcesoftware.com/free-developer-tools/blog/update-node-js/\"\u003enode 15 or 16 and npm 7 or later\u003c/a\u003e\u003c/li\u003e\n  \u003cli\u003enetlify-cli (use \"npm install -g netlify-cli\")\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/p\u003e\nYou will have to adapt commands and paths based on your environment (including digging into file \".gitpod.yml\") and install the dependencies by yourself. \u003cstrong\u003eWe won't provide support\u003c/strong\u003e to keep on track with schedule. However, we will do our best to give you the info you need to be successful. \u003cstrong\u003eThis is considered a more advanced path to take.\u003c/strong\u003e\n\u003c/details\u003e\n\u003cp/\u003e\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003e 2️⃣ What other prerequisites are there?\u003c/b\u003e\u003c/summary\u003e\n\u003chr\u003e\n\u003cul\u003e\n\u003cli\u003eYou will need a github account\u003c/li\u003e\n\u003cli\u003eYou should use Chrome or Firefox (other browsers might have trouble displaying Gitpod correctly)\u003c/li\u003e\n\u003cli\u003eYou will need an Astra DB account, but we'll cover that in the exercises\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/p\u003e\n\u003c/details\u003e\n\u003cp/\u003e\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003e 3️⃣ Do I need to pay for anything for this workshop?\u003c/b\u003e\u003c/summary\u003e\n\u003chr\u003e\n\u003cb\u003eNo.\u003c/b\u003e All tools and services we provide here are FREE. FREE not only during the session but also afterwards.\n\u003c/details\u003e\n\u003cp/\u003e\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003e 4️⃣ Will I get a certificate if I attend this workshop?\u003c/b\u003e\u003c/summary\u003e\n\u003chr\u003e\nAttending the session is not enough. You need to complete the homework detailed below and you will get a nice badge that you can share on linkedin or anywhere else \u003cstrong\u003e(open badge specification)\u003c/strong\u003e.\n\u003c/details\u003e\n\u003cp/\u003e\n\n\n## Materials for the Session\n\nIt doesn't matter if you join our workshop live or you prefer to do at your own pace, we have you covered. In this repository, you'll find everything you need for this workshop:\n\n- [Slide deck](./slides/slides.pdf)\n- [Discord chat](https://bit.ly/cassandra-workshop)\n- [\"cassandra\" on StackOverflow](https://stackoverflow.com/questions/tagged/cassandra)\n- [\"cassandra\" on DBA StackExchange](https://dba.stackexchange.com/questions/tagged/cassandra)\n\n## Homework\n\n\u003cimg src=\"tutorial/images/graphql-badge.png?raw=true\" width=\"200\" align=\"right\" /\u003e\n\nDon't forget to complete your upgrade and get your verified skill badge! Finish and submit your homework!\n\n1. Complete the practice steps from this repository, as described below, to the end;\n2. Insert (mutate) a **new show** or a **new genre** of your choice in the database;\n3. Take a single **screenshot** of the React app with all of the working Astra DB sections and showing the entry you just added;\n4. Submit your homework [here](https://dtsx.io/homework-intro-graphql).\n\nThat's it, done.\nWe will then grade the submissions: expect an email in a few days!\n\n# Let's start\n\n\n### Extra resources\n[graphql.org](https://graphql.org/) - The first place to learn about GraphQL\n\n[The Netflix DGS framework Tutorial](https://netflix.github.io/dgs/getting-started/) - Java/Spring GraphQL backend (used to generate this code)\n\n[Spring Initializr](https://start.spring.io/) - Used in the ^above tutorial to generate the Java/Spring backend starter\n\n[GraphiQL](https://www.gatsbyjs.com/docs/how-to/querying-data/running-queries-with-graphiql/) - GraphQL IDE included with The Netflix DGS Framework\n\n[Apollo client](https://www.apollographql.com/docs/react/) - Awesome GraphQL client for React/JS (not used here, but really solid, Netflix uses this)\n\n[Top 7 GraphQL IDEs](https://hasura.io/blog/top-7-graphql-ides-you-should-know-about-in-2021/) - A nice collection of cool GraphQL IDEs to use\n\n[create-react-app tutorial](https://create-react-app.dev/) - Create a React app from scratch (used to generate this code)\n\n[A Beginner's Guide to GraphQL](https://www.youtube.com/watch?v=c2fJ7T0N1Sk) - Ali Spittel's really awesome GraphQL starter video\n\n\n\n## 1. Login or Register to Astra DB and create database\n\n_**`ASTRA DB`** is the simplest way to run Cassandra with zero operations at all - just push the button and get your cluster. No credit card required, 40M read/write operations and about 80GB storage monthly for free - sufficient to run small production workloads. If you use up your credits the databases will pause, no charge, and you will be given the option to upgrade to a higher tier._\n\nLeveraging [Database creation guide](https://awesome-astra.github.io/docs/pages/astra/create-instance/#c-procedure) create a database. *Right-Click the following button* with *Open in a new TAB.*\n\n\u003ca href=\"https://astra.dev/yt-11-23\"\u003e\u003cimg src=\"tutorial/images/create_astra_db.png?raw=true\" /\u003e\u003c/a\u003e\n\n|Field|Value|\n|---|---|\n|**Database Name**| `workshops`|\n|**Keyspace Name**| `intrographql`|\n|**Regions**| Select `GOOGLE CLOUD`, then an Area close to you, then a region with no LOCK 🔒 icons: the LOCKed regions are the region not accessible to the Free Tier.\n\n\u003e **ℹ️ Note:** If you already have a database `workshops`, simply add a keyspace `intrographql` using the `Add Keyspace` button on the bottom right hand corner of the DB Dashboard page. You may have to \"Resume\" the database first in case it is in \"hibernated\" state.\n\nWhile the database is being created, you will also get a **Security token** (needed to authenticate with your database and start using it):\n**please IGNORE THIS ONE, as we will be soon creating a new, more powerful token for today**.\n\nThe status will change from `Pending` to `Active` when the database is ready, this usually only takes 2-3 minutes.\n\n\n\n## 2. Create a security token\n\n\u003e Note: this step is very important, as the token generated automatically for you with\n\u003e the database lacks some permissions we'll use in the workshop.\n\n[Create a token for your app](https://awesome-astra.github.io/docs/pages/astra/create-token/#c-procedure), _using the **\"Database Administrator\"** role_.\nKeep it handy for later use (best to download it in CSV format, as the values\nwill not be visible afterward).\nThis will provide authentication later when interacting with the database.\nToday, in particular, we will need the string labeled \"token\" (the one starting with `AstraCS:...`).\n\n\u003e **⚠️ Important**\n\u003e ```\n\u003e The instructor will show the token creation on screen,\n\u003e but will then destroy it immediately for security reasons.\n\u003e ```\n\n## 3. Launch Gitpod\n\n[Gitpod](https://www.gitpod.io/) is an 100% online IDE based on [Visual Studio Code](https://github.com/gitpod-io/vscode/blob/gp-code/LICENSE.txt?lang=en-US). To initialize your environment simply click on the button below _(CTRL + Click to open in new tab)_ You will be asked for you github account, as needed.\n\n**Warning**: for best results, open the link with Chrome or Firefox!\n\n[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/datastaxdevs/workshop-intro-to-graphql)\n\n\nThis will bootstrap your demo environment. Be patient, it will take a few minutes as everything loads up.\n\n\u003e **Note**: during loading of the Gitpod environment, a new tab will be tentatively opened\n\u003e with an URL such as `https://8080-datastaxdev-[...].gitpod.io/graphiql`.\n\u003e Please **CHECK YOUR POPUP BLOCKER** and allow it before continuing: this will be your GraphiQL interface!\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eShow me how Gitpod looks like for this workshop\u003c/strong\u003e\u003c/summary\u003e\n\nGitpod starts with a file explorer on the left (1), an editor panel on the top (2),\nand - in the case of this specific environment - two consoles side by side,\none to launch commands and later start the Node app (3) and one busy with\nrunning the Java backend (4). On the right you will find a console switcher to\neasily locate any console and make it active (but even just clicking\non the desired console would do the trick).\n\n![The shape of Gitpod](tutorial/images/gitpod-shape.png)\n\n\u003c/details\u003e\n\n\n## 4. Experiment with GraphiQL\nIt just so happens that [The Netflix DGS framework](https://netflix.github.io/dgs/getting-started/) comes with GraphiQL already integrated and ready for use. This is a wonderful tool you can use to explore graphQL queries and mutations. Let's experiment with this now!\n\n\u003e _Note:_ the GraphiQL should be open already in a new tab for you; in case it isn't for some reason,\n\u003e run this command in a Gitpod console and manually point a new tab to the URL it prints:```echo `gp url 8080`/graphiql```.\n\nSomething to point out here is there is no database just yet. We are powering the graphQL schema via the back-end Java application and the graphQL data is completely hardcoded.\nTake a look at both **`ShowsDatafetcher.java`** and **`GenresDatafetcher.java`** located in **`graphql-backend-examples/src/main/java/com/example/demo`**\nto find the simple implementations using DGS annotations `@DgsComponent` and `@DgsQuery`.\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eShow me how to open these files in Gitpod\u003c/strong\u003e\u003c/summary\u003e\n\nIn the left toolbar, choose the first tool (\"Explorer\") and navigate the directory to the desired directory; then, clicking on the files will open them in the editor (topmost panel on the right).\n\n![Open files in Gitpod](tutorial/images/open-java-DGS-files-in-gitpod.png)\n\n\u003c/details\u003e\n\n\n#### Now, let's try out some graphQL queries\nPlug these into the GraphiQL IDE that launched into a new tab from GitPod.\n\n```GraphQL\nquery justTitle {\n  shows {\n    title\n  }\n}\n```\n\n```GraphQL\nquery withReleaseYear {\n  shows {\n    title\n    releaseYear\n  }\n}\n```\n\n```GraphQL\nquery getOneShow {\n  shows (titleFilter: \"Ozark\") {\n      title\n      releaseYear\n  }\n}\n```\n\n```GraphQL\nquery ShowsAndGenres {\n  shows {\n    title\n    releaseYear\n  }\n  genres {\n    value\n  }\n}\n```\n\n![GraphiQL queries](tutorial/images/graphiql-queries.png)\n\n#### Compare the GraphQL schema\n\nThe objects known to a GraphQL API are defined starting from its \"Schema\".\nIn the case of our DGS Java application, the schema is found in\n`graphql-backend-examples/src/main/resources/schema/schema.graphqls`.\nTake a look at its contents: notice the special `Query` item that defines\nthe possible queries and, after that, the user-defined types available to\nthe API:\n\n```GraphQL\ntype Query {\n    shows(titleFilter: String): [Show]\n    genres(labelFilter: String): [Genre]\n}\n\ntype Show {\n    title: String\n    releaseYear: Int\n}\n\ntype Genre {\n    value: String!\n}\n```\n\n## 5. Experiment with Astra DB's GraphQL Playground\n\nOk, let's take this a step further and prepare the data layer for our app.\nAt this point you should have already [created your Astra DB database](#1-login-or-register-to-astradb-and-create-database).\nFollow the instructions below to launch the **GraphQL Playground** provided in **Astra DB**:\n\n#### ✅  Step 5a: Open GraphQL Playground:\n\n0. Ensure you are logged on to your [Astra](https://astra.datastax.com) account\n1. Click on the \"workshops\" database on the left (expanding the list if needed)\n2. Click `Connect` TAB\n3. Click the `APIs`  connection method\n4. Make sure `GraphQL API` is selected\n5. Locate the link to your GraphQL Playground in the text\n\n![Open Astra DB GraphQL Playground image](tutorial/images/open-playground-2.png)\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eClick here if you are using the \"New Astra Experience\" UI\u003c/strong\u003e\u003c/summary\u003e\n\n![Open Astra DB GraphQL Playground image, new Astra UI](tutorial/images/open-playground-2-wh.png)\n\n\u003c/details\u003e\n\n**Note**: in the following, we will refer to \"playground tabs\". These are _not_ the tabs\nin your browser, rather they are tabs _within_ the Playground application,\nto switch between the (logically distinct) realms of \"managing schema\" and \"managing data in the tables\"\n(more on that later).\n\n![Playground tabs VS Browser tabs](tutorial/images/tabs-vs-playgroundtabs-labeled.png)\n\n#### ✅  Step 5b: Insert the Astra DB Token to run schema queries\n\nIn the GraphQL Playground, **Populate HTTP HEADER** variable `x-cassandra-token` on the bottom of the page with your token (including the `AstraCS:` part).\n_This is the \"Database Administrator\" token you created earlier on the Astra DB dashboard (Step 2 above)._\n\n**Note**: make sure you are on the **`graphql-schema`** playground tab in this step, as this image illustrates:\n\n![GraphQL Playground and token header, Schema playground tab](tutorial/images/graphql-playground.png)\n\n\u003e Note: the GraphQL Playground starts with a ready-to-use _temporary token_ as the `x-cassandra-token` header. But we want the queries run in the Playground\n\u003e to be identical to those that the Netlify functions will run from code, so **please replace the token with your DB token as instructed**.\n\n#### ✅  Step 5c: Create a table in the GraphQL Playground\n\nRun the following mutation in the `graphql-schema` playground tab, making sure to replace `intrographql` in the URL if you used a different keyspace name:\n\n- Copy the following mutation on the left panel\n\n```GraphQL\nmutation {\n  reference_list: createTable(\n    keyspaceName:\"intrographql\",\n    tableName:\"reference_list\",\n    ifNotExists:true\n    partitionKeys: [ \n      { name: \"label\", type: {basic: TEXT} }\n    ]\n    clusteringKeys: [\n      { name: \"value\", type: {basic: TEXT}, order: \"ASC\" }\n    ]\n  )\n}\n```\n\nClick on the arrow in the middle of the screen to execute the query.\n\n![Execute a query in GraphQL Playground](tutorial/images/playground-1.png)\n\n## 6. Insert data to DB using the GraphQL Playground\n\n#### ✅  Step 6a: Adjust the second playground tab to your keyspace\n\nIn the GraphQL playground, switch to the second Playground tab (`graphql`). Edit the ending of the URL _shown within the Playground page_ from `system` to the keyspace name `intrographql`:\n\n![GraphQL URL ending](tutorial/images/graphql-url-ending.png)\n\n#### ✅  Step 6b: Set the token to run data queries\n\nPopulate the **HTTP HEADER** variable `x-cassandra-token` on the bottom of the page with your DB token as shown below _(Note: you did this for the `graphql-schema` playground tab, now repeat for the `graphql` playground tab!)_\n\n![GraphQL Playground and token header, GraphQL playground tab](tutorial/images/graphql-playground-2b.png)\n\n#### ✅  Step 6c: Insert genre names with the Playground\n\nIn the GraphQL Playground, populate the `reference_list` table with all values:\ncopy the following mutation on the left panel\n\n```GraphQL\nmutation insertGenres {\n  action: insertreference_list(value: {label:\"genre\", value:\"Action\"}) {\n    value{value}\n  }\n  anime: insertreference_list(value: {label:\"genre\", value:\"Anime\"}) {\n     value{value}\n  }\n  award: insertreference_list(value: {label:\"genre\", value:\"Award-Winning\"}) {\n     value{value}\n  }\n  children: insertreference_list(value: {label:\"genre\", value:\"Children \u0026 Family\"}) {\n     value{value}\n  }\n  comedies: insertreference_list(value: {label:\"genre\", value:\"Comedies\"}) {\n     value{value}\n  }\n  documentaries: insertreference_list(value: {label:\"genre\", value:\"Documentaries\"}) {\n     value{value}\n  }\n  drama: insertreference_list(value: {label:\"genre\", value:\"Dramas\"}) {\n     value{value}\n  }\n  fantasy: insertreference_list(value: {label:\"genre\", value:\"Fantasy\"}) {\n     value{value}\n  }\n  french: insertreference_list(value: {label:\"genre\", value:\"French\"}) {\n     value{value}\n  }\n  horror: insertreference_list(value: {label:\"genre\", value:\"Horror\"}) {\n     value{value}\n  }\n  independent: insertreference_list(value: {label:\"genre\", value:\"Independent\"}) {\n     value{value}\n  }\n  music: insertreference_list(value: {label:\"genre\", value:\"Music \u0026 Musicals\"}) {\n     value{value}\n  }\n  romance: insertreference_list(value: {label:\"genre\", value:\"Romance\"}) {\n     value{value}\n  }\n  scifi: insertreference_list(value: {label:\"genre\", value:\"Sci-Fi\"}) {\n     value{value}\n  }\n  thriller: insertreference_list(value: {label:\"genre\", value:\"Thriller\"}) {\n     value{value}\n  }  \n}\n```\n\nClick on the arrow in the middle of the screen to execute the query.\n\n## 7. Retrieve values from DB using the GraphQL Playground\n\n#### ✅  Step 7a: Read genres with a query in the Playground\n\nIn the GraphQL Playground (staying on the `graphql` playground tab), list values from the table with the following query:\n\n```yaml\nquery getAllGenre {\n    reference_list (value: {label:\"genre\"}) {\n      values {\n      \tvalue\n      }\n    }\n}\n```\n\n*👁️ Expected output*\n![Playground getAllGenre query result](tutorial/images/graphql-playground-3.png)\n\n## 8. Start up React\n\nSo far we have executed GraphQL queries and mutations by hand from specific UIs.\nNow it's time to start the React client app and query the GraphQL endpoints from it!\n\n\u003e \"Endpoints\", two of them. Each GraphQL server exposes a single endpoint for everything,\n\u003e but remember this app will query both the local DGS app and the Astra DB server!\n\nFirst you need to run a couple commands to get things set up:\nin your **`GitPod`** IDE navigate to the \"Client\" terminal\n*(it should already be open for you on the bottom left)*\nand make sure you are in the **`workshop-intro-to-graphql/graphql-client-examples`** directory.\n**This is where you'll be running the nodejs/React app.**\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eRemind me what is this \"client terminal\" ...\u003c/strong\u003e\u003c/summary\u003e\n\nIt is the block labeled as \"3\". Click on it, or use the switcher (5):\n\n![The shape of Gitpod](tutorial/images/gitpod-shape.png)\n\n\u003c/details\u003e\n\n#### ✅ Step 8a: Execute the following command\n```shell\nnpm install -g netlify-cli\n```\n\nThis will install the **Netlify CLI** (command line interface) which our **React/JS** app uses in conjunction with the serverless functions we've setup to talk to our **graphQL** endpoints.\n\n#### ✅  Step 8b: Then, execute\n```shell\nnetlify dev\n```\n\nThis will start the **React/JS** application and display results from both the **`Shows`** and **`Genres`** **graphQL** queries and endpoints we were just experimenting with.\n\nYou should see Gitpod's mini-browser opening up by itself and showing the client application wihtin Gitpod.\n\n\u003e _Note:_ the client, at this point, should be opened in the mini-browser within Gitpod; to open it manually,\n\u003e run this command in a Gitpod console and point a new tab to the URL it prints:```echo `gp url 8888` ```.\n\n#### Compare javascript code to our graphQL queries from above\nIf you take a look at both **`getShowsBackend.js`** and **`getGenresBackend.js`** located in **`graphql-client-examples/functions`** you should notice that both use the **same exact** **graphQL** queries that we used above.\n\n```javascript\nconst query = `\n    query getAllShows {\n      shows {\n        title\n        releaseYear\n      }\n    }\n  `\n```\n\n```javascript\n  const query = `\n    query getAllGenres {\n      genres {\n        value\n      }\n    }\n  `\n```\n\nAll of the javascript wrapped around these is simply there to call the **graphQL** endpoint with the given query and pass the responseBody back to the calling function.\n\n#### Now for the cool part\n\nTake a look at **`Shows.js`** and **`Genres.js`** located in **`graphql-client-examples/src/components/`**. In both cases they use **React** state, `gqlResult`\n\n```javascript\n  const [gqlResult, setGqlResult] = useState(null)\n```\n\nto receive the responseBody from from our **graphQL** queries, set the **React** state, and inject the values dynamically into the DOM. Check out the following javascript snippet from **`Shows.js`**.\n\n```javascript\n// Asynchronously fetch any \"shows\" graphQL data from the Java backend\n// using the getShowsBackend serverless function to call out to the\n// Netflix DGS Java graphQL endpoint\nconst response = await fetch(\"/.netlify/functions/getShowsBackend\", {\n    method: \"POST\",\n})\nconst responseBody = await response.json()\nsetGqlResult(responseBody) // on response set our graphQL result state\n```\n\nNotice how the fields (title, releaseYear) match our **graphQL** `Shows` schema exactly.\n\n```javascript\n// Finally, if all other checks pass get the data\n// from the payload via gqlResult state and inject it into the DOM\n// Notice how the payload example below and the fields \"title\" and \"releaseYear\" match exactly\n// {\"data\":{\"shows\":[{\"title\":\"Stranger Things\",\"releaseYear\":2016},{\"title\":\"Ozark\",\"releaseYear\":2017}...\nreturn gqlResult.data.shows.map(({ title, releaseYear }) =\u003e (\n    \u003cdiv key={title}\u003e\n        \u003cp\u003e\n        {title}: {releaseYear}\n        \u003c/p\u003e\n    \u003c/div\u003e\n  ));\n```\n\nNotice how the field (value) matches our **graphQL** `Genres` schema exactly.\n\n```javascript\n// Finally, if all other checks pass get the data\n// from the payload via gqlResult state and inject it into the DOM\n// Notice how the payload example below and the field \"value\" match exactly\n// {\"data\":{\"genres\":[{\"value\":\"Action\"},{\"value\":\"Anime\"}...\nreturn gqlResult.data.genres.map(({ value }) =\u003e (\n    \u003cdiv key={value}\u003e\n        \u003cp\u003e\n        {value}\n        \u003c/p\u003e\n    \u003c/div\u003e\n  ));\n```\n\n## 9. Hook the database up to the React client app\n\nThe next step is to make the client able to retrieve the genres and the shows\nfrom the database, by querying Astra DB's GraphQL API. To achieve this,\nit's time to provide connection details (addresses, secrets) to the\nserverless Netlify functions which will back the React client.\n\n#### ✅ Step 9a: Initialize Astra CLI\nIn the **`GitPod`** IDE, click on the \"Client\" terminal to make it active, hit `Ctrl-C` to stop the running client, if any, and make sure you are in the **`workshop-intro-to-graphql/graphql-client-examples`** directory.\n\nNow you will create a `.env` file with connection info (addresses and secrets) for the Netlify function to be able to reach both the local backend and your Astra DB's GraphQL endpoint.\nYou will use the Astra command-line interface to prepare a dot-env file for you; then you will complete it by adding a line defining the address of the local backend (i.e. the DGS locally-running GraphQL API).\n\nRun the following command and provide your **DB Administrator** token string (starting with `AstraCS:...`) when prompted:\n\n```\nastra setup\n```\n\n#### ✅ Step 9b: Configure database credentials\n\nOnce you get a \"Configuration has been saved\" confirmation, proceed with:\n\n```\nastra db create-dotenv workshops -k intrographql\ncat .local-backend.env \u003e\u003e .env\ngp open .env\n```\n\nThe credentials are now all set up: your dot-env file should be now shown in the editor for you to check its contents.\nYou will see several lines pertaining to Astra DB (not all of which will be used by today's client)\nand, at the end, a single setting about the Java GraphQL API you tested earlier.\n\nHere is how the `.env` might look like (as a reference, check out the provided `.env.sample`):\n\n![Sample dot-env file](tutorial/images/dot-env-2.png)\n\n\u003e If you are preparing the file manually (i.e. as opposed to using the `astra-cli` tool), be aware that the only\n\u003e variables needed by the React client are: `ASTRA_DB_APPLICATION_TOKEN`, `ASTRA_DB_GRAPHQL_URL`\n\u003e and `JAVA_GRAPHQL_ENDPOINT`.\n\n#### ✅ Step 9c: Start your React app again\n\nLaunch the following command once more:\n```shell\nnetlify dev\n```\n\n#### ✅ Step 9d: Verify data load\nAt this point your app should be running with a bunch of data displayed in the **`Shows`**, **`Genres,`** and **`ReferenceList`** sections, but notice the **`ShowsByName`** section displays **\"Error :(\"**\n\n![Error in Shows by name](tutorial/images/error_shows_by_name.png)\n\n#### Can you figure out what's going on here?\nLet's break this down.\n\n* We just added the database configuration and the **`ReferenceList`** section is populated which tells us our DB config and graphQL endpoints are configured properly\n\n* In the GraphQL Playground we added a schema for the **`reference_list`** table and added some data to the table, but we never created a schema for the **`ShowsByName`** section\n\n* If you take a look at the **`getShowsAstra.js`** script in **`graphql-client-examples/functions`** you can see the graphQL being used to query for data\n```javascript\nexports.handler = async function (event) {\n  const query = `\n    query getAllShows {\n      show_by_name {\n        values {\n          title\n          releaseYear\n        }\n      }\n    }\n  `\n```\n\n#### ✅ Step 9e: Test this query\n\nGo back to the GraphQL **`graphQL`** playground tab.\n\nCopy this into the playground and press the _\"play\"_ button to execute the query. **NOTE, you can simply append the query to the end of the list and then choose the query you wish to execute when you hit the \"play\" button.**\n\n```GraphQL\nquery getAllShows {\n      show_by_name {\n        values {\n          title\n          releaseYear\n        }\n      }\n    }\n```\n\n![GraphQL getAllShows execution](tutorial/images/graphql-getallshows.png)\n\n#### View Results\nNotice what happened here. We have a validation error because there is no schema associated with the query we just executed. GraphQL uses a typed validation system so this is something to expect if a query is malformed, missing a schema, or something along those lines. You will want to control for this in your code.\n\n![GraphQL \"Field undefined\" error](tutorial/images/graphql-field-undefined-error.png)\n\n#### ✅ Step 9f: Create the missing table\n\nTo fix up the schema issue, and resolve the error,\ncreate the **`ShowsByName`** table with a graphQL mutation to fix the app.\nExecute the following mutation in the **`graph-schema`** Playground tab\n\n```GraphQL\nmutation CreateShowsTable {\n  createTable(\n    keyspaceName: \"intrographql\"\n    tableName: \"show_by_name\"\n    partitionKeys: [{\n      name: \"title\", type: {basic:TEXT}\n    }]\n    values:[{\n      name: \"releaseYear\", type: {basic:INT}\n    }]\n  )\n}\n```\n\n![GraphQL CreateShowsTable query](tutorial/images/graphql-CreateShowsTable.png)\n\n#### ✅ Verify result\nOnce executed you should see a result like this\n\n![GrahQL CreateShowsTable result](tutorial/images/graphql-CreateShowsTable_result.png)\n\n#### ✅ Step 9g: Add some data\nNow, go back to the **`graphql`** playground tab and add the following mutation\n```GraphQL\nmutation insertShows {\n  stranger: insertshow_by_name (\n    value: {\n      title: \"Stranger Things\",\n      releaseYear: 2016}) {\n  \tvalue{title}\n  }\n  ozark: insertshow_by_name (\n    value: {\n      title: \"Ozark\",\n      releaseYear: 2017}) {\n  \tvalue{title}\n  }\n}\n```\n\n![GraphQL \"insertShows\"](tutorial/images/graphql-insertShows.png)\n\n#### ✅ Check the result\n\n![GraphQL insertShows, result](tutorial/images/graphql-insertShows_result.png)\n\n#### ✅ Step 9h: Check the client again\n\nFinally, refresh your React app.\n\nNotice this no longer displays an error. Now it correctly displays the data you just inserted (mutated). It might be fun to add some of your own data to this schema and refresh your page.\n\n![GraphQL, client showing shows from DB](tutorial/images/graphql-client-showing-shows.png)\n\n#### Play a bit more!\n\nFeel free to experiment with a couple more graphQL queries now that you have some data in the table\n\nQueries usually offer some way to restrict the results returned,\nin the form of parameters passed to queries. Recall the original `getAllShows`, repeated here for convenience:\n\n\n```GraphQL\nquery getAllShows {\n  show_by_name {\n    values {\n      title\n      releaseYear\n    }\n  }\n}\n```\n\nNow let's see a way to pass a `title` parameter to the query and just get\nmatching values (a single entry, in this case):\n\n```GraphQL\nquery getOneShow {\n  show_by_name (value: {title: \"Ozark\"}) {\n    values {\n      title\n      releaseYear\n    }\n  }\n}\n```\n\nThe following query, which uses the [more general `filter` syntax](https://docs.datastax.com/en/astra/docs/develop/dev-with-graphql-cql-first.html#_retrieve_data),\nis completely equivalent to the previous one:\n\n```GraphQL\nquery getOneShowF {\n  show_by_name(filter: {title: {eq: \"Ozark\"}}){\n    values {\n      title\n      releaseYear\n    }\n  }\n}\n```\n\n\n### That's it, you did it! Nice job!\n\nWe hope this workshop gave you enough information on GraphQL to be dangerous and start you on a journey to using GraphQL in your own apps.\nAlso, don't forget your [HOMEWORK](#homework).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdatastaxdevs%2Fworkshop-intro-to-graphql","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdatastaxdevs%2Fworkshop-intro-to-graphql","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdatastaxdevs%2Fworkshop-intro-to-graphql/lists"}