In this part we'll be seeing how to start the apollo client in react, use mutations and signin our first user from the web.
Previously we saw the first steps in the project structure and the routing system, but we didn't create the containers that renders those url paths, so let's do it!
But first we have to configure our apollo-client in order to use apollo in react. For this let's install some packages: npm i @apollo/client apollo-utilities graphql apollo-link-ws subscriptions-transport-ws graphql-tag
.
./graphql/client.js
import { ApolloClient, HttpLink, InMemoryCache, split } from "@apollo/client";
import { WebSocketLink } from "apollo-link-ws";
import { getMainDefinition } from "apollo-utilities";
const server_url = process.env.SERVER_URL;
const httpLink = new HttpLink({
uri: "http://server_url",
});
// Create a WebSocket link:
const wsLink = new WebSocketLink({
uri: `ws://server_url`,
options: {
reconnect: true,
},
});
const link = split(
// split based on operation type
({ query }) => {
const definition = getMainDefinition(query);
return (
definition.kind === "OperationDefinition" &&
definition.operation === "subscription"
);
},
wsLink,
httpLink
);
export const client = new ApolloClient({
cache: new InMemoryCache(),
link: link,
});
There is a few important things happening here.
-
ApolloClient
will allow us to compose a client object to use it as a provider so our app can access this api from any component under the main component node we define. - The
server_url
constant is the path that we got from deploy our server, if we are running this locally it would be something likelocalhost:8080/graphql
. - The
HttpLink
and theWebSocketLink
are link creators, we'll use those links to comunicate with the sockets and http api we defined in our backend. 4.Thesplit
operator let us redirect the queries, mutations and subscriptions to the specific endpoints they correspond to.
Now we can provide this client to all our app so we can excecute the graphql operations wherever we like.
./App.jsx
import { ApolloProvider } from "@apollo/client";
import React from "react";
import { HashRouter } from "react-router-dom";
import AppRouter from "./AppRouter";
import { client } from "./graphql/client";
import appRoutes from "./routes/app.routes";
const App = () => {
return (
<div className="App">
<ApolloProvider client={client}>
<HashRouter basename="/">
<AppRouter routes={appRoutes} />
</HashRouter>
</ApolloProvider>
</div>
);
};
export default App;
Now we actually can connect to the backend, but first we have to define what we want to say to it, or what we want it to answer us.
To do this let's define our first operation, the signin mutation.
./graphql/mutations/signIn.js
import gql from "graphql-tag";
export default gql`
mutation signInMutation($usr: String, $password: String) {
signInUser(usr: $usr, password: $password) {
usr
name
type
token
}
}
`;
gql
is basically a graphql interpreter that reads a string and translate it into graphql language. You may have notice that this string is exactlly the same we tested in the playground, shout-out to the playground!
Now we can consume this specific endpoint.
Let's login.
./containers/Login/Login.jsx
import { useMutation } from "@apollo/client";
import React, { useEffect } from "react";
import Signin from "../../components/Signin/Signin";
import SIGNIN_USER from "../../graphql/mutations/signIn";
const Login = () => {
const [signInUser, { data, error, loading }] = useMutation(SIGNIN_USER);
const onSubmitSignin = (fields) => {
signInUser({
variables: { usr: fields.username, password: fields.password },
});
};
useEffect(() => {
if (!loading) {
console.log(data);
if (data?.signInUser.usr) {
console.log("Should let me in");
} else {
console.log("You shall not pass");
}
}
}, [data, loading]);
return (
<div>
<Signin onSubmit={onSubmitSignin}></Signin>
</div>
);
};
export default Login;
As always, let's check this piece of code.
- The
useMutation
hook allow us to execute theSIGNIN_USER
mutation as a functionsignInUser
, also it let us check the data, if an error occur and whereas our petition is loading. - The
Signin
component is just a form that resolve the username and the password, so it's submit function fires thesignInUser
mutation with those params. - Using the
useEffect
hook we can check for data and loading states to change.
To check if everything is ok you could create a new user in the playground, and come back to the app to try those credentials. The console should print Should let me in
.
In the next part we'll use the routing system we created so we can navigate to the chatroom container. As an exercise you should try to build the signup flow (hint: it's pretty similar).
Top comments (0)