The funny part is about to begin.

In this section we are going to set our graphql queries, and schemas so them matches the sql models created on the first part, and the authentication setted on the second part.
Now we can create a folder graphql to wrap the users and messages schemas.
./graphql/schemas/messages.schema.js
const MESSAGE_TYPES = `
type Message { id: String, text: String, date: String, usr: String }
`;
module.exports = { MESSAGE_TYPES };
./graphql/schemas/users.schema.js
const USERS_TYPES = `
type User { usr: String, name: String, type: String, password_digested:String, token: String }
`;
module.exports = { USERS_TYPES };
This schemas are only objects that matches the types defined in the sql section for the messages and users.
Now we can use these schemas to implement mutations and queries with the graphql api apollo.
./graphql/index.js
const { USERS_TYPES } = require("./schemas/users.schema");
const { MESSAGE_TYPES } = require("./schemas/messages.schema");
const { getMessages, addMessage } = require("../data/sql/messages");
const { signin, signup, findUser } = require("../data/sql/users");
const { gql } = require("apollo-server-express");
const { PubSub } = require("apollo-server");
First lets take a look to these weird graphqlrequires.
gql query parser, it allows us to write queries in string format.
PubSub is the magic package that will help us to get the real time functionality. It uses socket subscriptions under the hood to achive that.
Now let's create the mutations!
const pubsub = new PubSub();
const QUERY = gql`
type Query {
user(usr: String): User
messages: [Message]
}
`;
const MUTATION = gql`
type Mutation {
createMessage(text: String, date: String, usr: String): Message
signInUser(usr: String, password: String): User
signUpUser(usr: String, name: String, password: String, type: String): User
}
`;
const SUBSCRIPTION = gql`
type Subscription {
messageAdded: Message
}
`;
const typeDefs = [QUERY, MUTATION, SUBSCRIPTION, USERS_TYPES, MESSAGE_TYPES];
Let's analize this code:
We create a new instance of the PubSub object.
The
QUERYconstant is a graphql query that defines how our server is going to search for users and messages.The
MUTATIONconstant is a graphql mutation that defines 3 functionscreateMessage,signInUser,signUpUser, and the parameters these functions requires.The
SUBSCRIPTIONconstant is a graphql subscription that will be our connection to the real time messages stream.The
typeDefsis an object required by the graphql server in order to show documentation, and basically this is how the server knows what it can query and mutate.
Now we can actually add funcionality to those things defined before:
const resolvers = {
Subscription: {
messageAdded: {
subscribe: () => {
return pubsub.asyncIterator(["MESSAGE_ADDED"]);
},
},
},
Mutation: {
signInUser: async (parent, args) => {
return await signin({ ...args });
},
signUpUser: async (parent, args) => {
return await signup({ ...args });
},
createMessage: async (parent, args) => {
pubsub.publish("MESSAGE_ADDED", {
messageAdded: { ...args },
});
return await addMessage({ ...args });
},
},
Query: {
messages: async () => {
return await getMessages();
},
user: async (paretn, args) => {
return await findUser(args.usr);
},
},
};
module.exports = { typeDefs, resolvers };
The
resolversobject is, as the typeDefs object, used by the server. Basically are the functions executed by the server.The
Subscriptionobject is composed by a subscription to the 'MESSAGE_ADDED' topic. This means each time this topic is used for something (like adding a new message), themessageAddedsubscription will notice.The
Mutationobject is composed by the 3 functions defined on thetypeDefs. These functions in turn use the functions of signin, signup, and addMessage. The args parameter should match the defined on thetypeDefs.
3.1 ThecreateMessagefunction is using the pubsub object to subscribe into a topic called 'MESSAGE_ADDED'.The
Queryobject is returning whatever that is on the messages table and the user info given an username.Finally we can export the
typeDefsand theresolversso we can start our server.
In the next part we'll be setting up the final details to start our server and run some manual tests to check if everything is ok.
Top comments (0)