Querying Listings
Numerous tools and libraries exist to help clients make GraphQL requests to a GraphQL API. Before we begin to introduce a third-party library to help make our GraphQL requests, we'll look to make our requests with the help of the window Fetch API. In this lesson, we'll begin to make the connection between our React client and Node server and see if we can query the listings query from our GraphQL API.
📝 This lesson's quiz can be found - here. 🗒️ Solutions for this lesson's quiz can be found - here.
We'll look to make our first interaction with the local GraphQL API we've set up on the server. There's a large number of tools in the ecosystem that is geared to help clients make GraphQL queries. And these tools provide a lot of value with which we'll see shortly, but they're not a requirement to making GraphQL requests.
In the next couple of lessons, we'll be taking our time and looking to make our GraphQL requests through some simple means which will give us a good understanding of what it takes to make a GraphQL request.
Here's a gameplan of what we'll do to make our first request.
Gameplan#
We'll invoke a POST
HTTP method#
GraphQL supports both the POST and GET methods with some requirements in each.
In traditional REST applications, POST
and GET
are denoted to invoke what kind of request is going to be made. In GraphQL, however, we address retrieving or mutating information with queries and mutations. The one main distinction between GraphQL queries or mutations is that mutations are executed one after the other while queries are executed in parallel. Since our GraphQL server is served over HTTP, we can make either a POST
or GET
request to invoke a GraphQL query or mutation.
Most GraphQL clients use the POST
HTTP method to both retrieve and persist data with which we'll be doing as well.
We'll specify the content type of our POST request as application/json
#
We'll pass our GraphQL documents (i.e. queries) as a JSON object.
We'll reference the URL of the API endpoint when we make our requests#
Our GraphQL API is served over a single endpoint (http://localhost:9000/api
), so we'll reference this single endpoint in all our requests.
Server fetch()
#
We'll be using the native browser fetch()
method to make our GraphQL requests.
If you're using the Internet Explorer browser to run the React project, the window
fetch()
method is unsupported. We'll suggest using Chrome/Firefox or installing afetch()
polyfill library.
We'll create our server fetch()
function in a new lib/
folder within src/
.
client/
src/
lib/
// ...
// ...
The src/sections/
folder will be responsible for containing the main section components of our app. The src/lib/
folder will be where we introduce code that is to be most likely shared between the different components in our app.
We'll create an api/
folder within lib/
. We'll additionally create an index.ts
and server.ts
file inside the api/
folder.
client/
src/
lib/
api/
index.ts
server.ts
In the src/lib/api/server.ts
file, we'll export a server
const
object that will remain empty for now.
export const server = {};
We'll re-export the server
object from the src/lib/api/index.ts
file.
export * from "./server";
In the server
object, we'll define a property on the object that's given a label of fetch
. This property is to be a function.
export const server = {
fetch: () => {}
};
In the server.fetch()
function, we'll use the window fetch()
function to help make our request. We'll assign the results of the window fetch()
method to a constant variable we'll call res
(i.e. response).
export const server = {
fetch: () => {
const res = fetch();
}
};
Window fetch()
is a promise. We want the results of the promise to be assigned to the res
constant variable. We'll use the async
/await
syntax by making the server.fetch
property function an async
function and placing the await
expression on the window fetch()
function:
export const server = {
fetch: async () => {
const res = await fetch();
}
};
When our server.fetch()
function gets called, we'll expect an object to contain the GraphQL document. We'll label the GraphQL document as query
regardless if a GraphQL query or mutation is being invoked.
Let's create an interface for this object body, that we'll call Body
, that will have a query
field of type string
. We'll dictate that the server.fetch()
function is to accept a body
argument of type Body
.
interface Body {
query: string;
}
export const server = {
fetch: async (body: Body) => {
const res = await fetch();
}
};
With our server
fetch()
function expecting the request body object, we can begin to build out the window fetch()
method.
/api
proxy#
The first argument of the window fetch()
method is a required argument that is the reference to the path of the resource we want to fetch. In our instance, the path or endpoint of our API is http://localhost:9000/api
when our server is running. If we were to directly use the http://localhost:9000/api
in our fetch()
method, our client Webpack server (http://localhost:3000
) will attempt to load a resource from a different origin (http://localhost:9000
). This will essentially be performing Cross-Origin Resource Sharing and for security reasons, browsers may reject the ability for our client to make the request to the server. To avoid this, we can have our Webpack Server proxy requests intended for our API Server.
This page is a preview of TinyHouse: A Fullstack React Masterclass with TypeScript and GraphQL