- Part 1 - Getting Started
- Part 2 - App Service with dotnet
- Part 3 - Serverless with JavaScript
- Part 4 - CosmosDB and GraphQL
- Part 5 - Can We Make GraphQL Type Safe in Code?
- Part 6 - GraphQL Subscriptions with SignalR
- Part 7 - Server-Side Authentication
- Part 8 - Logging
- Part 9 - REST to GraphQL
- Part 10 - Synthetic GraphQL Custom Responses
- Part 11 - Avoiding DoS in queries
- Part 12 - GraphQL as a Service
- Part 13 - Using React with DAB and SWA (this post)
- Part 14 - Using Blazor with DAB and SWA
In the last post I introduced you to a new project we’ve been working on, Data API builder for Azure Databases (DAB) and in this post I want to look at how we can use it in Azure, and that will be through one of my favourite Azure services, Azure Static Web Apps, for you see, as part of the announcement today of DAB, we’ve announced that it is available as a feature of SWA (called Database Connections), so let’s build a React app!
Local Development
One of the neat things about working with SWA is that we have a CLI tool which emulates the functionality of SWA, and with today’s announcement, we can use it to emulate the Database Connections feature, so let’s get started. First off, we need to ensure we have the latest version of the CLI installed, so let’s run the following command:
|
|
For the Database Connections, we’ll use the same configuration that we had in the last post, so let’s copy the dab-config.json
and schema.graphql
into the data
folder of our repo, and rename the dab-config.json
to staticwebapp.database.config.json
. Next, I’m going to scaffold out a new React app (using Vite), so let’s run the following command:
|
|
Lastly, we’ll initialise the SWA CLI:
|
|
Follow the prompts and adjust any of the values you require (the default Vite template uses npm run dev
for the dev server but the SWA CLI init will want to use npm start
, so you’ll need to adjust one of those values). When completed, you should have a swa-cli.config.json
like this:
|
|
Notice the last line, "dataApiLocation": "data"
, this is the location of the folder that contains the schema.graphql
and staticwebapp.database.config.json
files which are going to be used by the Database Connections feature. Now, let’s start the SWA CLI:
|
|
Once the CLI has started you can browse the GraphQL schema in your choice of IDE by providing it with the address http://localhost:4280/data-api/graphql.
Building a React application
It’s time to build the React application, I won’t cover all the details (you’ll find the full example on my GitHub), instead I’ll focus on the GraphQL integration.
Since we have a TypeScript application, we can adapt the pattern I discussed in part 5 on type-safe GraphQL, using GraphQL Code Generator to generate the types for us. To do this, we’ll need to install the following packages to the frontend
project:
|
|
We’ll then initialise the GraphQL Code Generator:
|
|
Follow the setup guide to create the config file like so:
|
|
Great, we’re almost ready to go, the last thing we’re going to need is a GraphQL client, and for that, we’ll use Apollo Client, so let’s install that:
|
|
Integrating GraphQL
It’s time to integrate GraphQL into our application, and I’m going to do that by creating a useQuestions
hook, which will return the questions from the database. First, let’s create the hook:
|
|
This might error at the moment as the graphql
function doesn’t exist, which is to be expected as we haven’t generated it yet via the GraphQL Code Generator. Let’s do that now:
|
|
This assumes that the codegen
script is in the package.json
file, if not, you’ll need to run npx graphql-codegen
instead.
With the error sorted, let’s continue with the hook. Initially we’ve defined the GraphQL query in the getQuestionsDocument
variable, and then we’ve used the graphql
function create a TypedDocumentNode
which is the type that Apollo Client expects. Next, we’ll use the useQuery
hook to execute the query, and then we’ll return the data from the query:
|
|
Admittedly, we could just return the data.questions.items
from the hook, but I don’t want to do that because the data structure contains two fields I’d prefer to merge, correct_answer
and incorrect_answers
, so that we can shuffle the answers in a random way and then have the application only know about all the answers as a single array. To do this, we’ll use the useEffect
hook to merge the data, and then we’ll return the merged data:
|
|
Since the questions
that we return will have some of the same fields as the object returned from the original GraphQL query, we may as well use the Omit
type to remove the incorrect_answers
field from the QuestionModel
type. We can then add the answers
field to the type, which is an array of strings that contains the correct_answer
and the incorrect_answers
shuffled in a random order.
Now all that’s left is to add the Apollo Client provider to our React application:
|
|
And then use the hook in the App
component (I’ll omit that for brevity, you can check it out in the GitHub repo). But with it all configured, here’s how it looks:
Conclusion
In this post we’ve taken a look at how we can use the new Database Connections feature of Azure Static Web Apps to connect to a Cosmos DB database and expose it as a GraphQL endpoint, without having to write the server ourself. We’ve also seen that this can be done entirely via the local emulator for SWA, allowing us to rapidly iterate over the application without having to deploy it each time.
While we didn’t go through the deployment aspect in this post specifically, you can learn how to do that through our docs.