ToEatApp Rails-React-Relay-GraphQL Tutorial - Mutations
If you are curious about how these different tools are configured to work together, you might look at the application setup post. If you are unclear about the Relay query and client side data graph structure, you might look at the relay/graphql queries post.
schema.json
Anytime you change code on the server that tells or changes any of the structure in how Graphql is organizing data for Relay, you must update schema.json
(bin/rake generate_graphql_schema
) and restart the webpack process.
Mutations
REST ideology categorizes http request by the type of action being enacted upon a database. One might recognize these actions as GET
,POST
, PUT
and DELETE
, which generally map to show, create, edit and destroy information. Graphql operates in a bit more simplistic fashion, ie, the client is either reading information from the database or writing information to it. Writing to the database becomes synonymous with Mutation
.
Also notice on the server, instead of a typical REST
styled API, we will be routing ALL database read/write requests through the same server endpoint.
Notice that the TrucksController
responds to #graphql
which has the sole function of receiving a query and returning whatever the query happens to return to the client. If you find yourself having an immediate, viscerally negative reaction to this thought, you are not alone. This is part of the code that represents a binary move away from REST ideology.
Creating a Food Truck
Let’s consider for a moment that you aren’t happy with the default FoodTruck options at toeatapp.startuplandia.io. Like the happy makers we are, we will need to create this FoodTruck.
Notice in index.jsx
we render the React component, CreateFoodTruck
.
Importantly, when this.createFoodTruck
gets called, the function receives some basic information about the truck (name, homeTown) and passes that information to new CreateFoodTruckMutation(foodTruckDetails)
. Let’s look at CreateFoodTruckMutation
Let’s consider the main points related to the above Mutation
definition. We are binding this client side Mutation
to the server-side Mutation
with the code return Relay.QL mutation { create_food_truck }
where create_food_truck
is defined in…
The next important point to notice in the CreateFoodTruckMutation
is getVariables()
which gives us the opportunity to define the information that will flow from the client to the server, in this case, this.props
refers to the arguments passed to new CreateFoodTruckMutation(someArgs)
as in the below.
Continuing through CreateFoodTruckMutation
we notice the function getFatQuery()
, which tells our mutation about all the possible information in our client side data graph that COULD be impacted by the write we are preparing to make in the database.
This is a very important part of the setup as it allows Relay to understand the maximum possible impact this mutation could have on our data graph. Specifically, we are telling Relay that a CreateFoodTruckMutation
could result in changes to food_truck
and fleet
.
Finally, notice in CreateFoodTruckMutation
the call to getConfigs()
, which tells Relay about the relevance of information that returns from the server to the client, after the write is executed.
In this case, we are telling Relay that the Fleet
of id this.props.fleetId
will be updated, which Relay then uses internally to update the information that Relay is currently tracking as associate with which Fleet happens to be in question.
The tie in back to our React component and the DOM occurs in conjunction with the above getConfigs()
call. Once Relay has been told that ‘hey Fleet with id n has been changed’ Relay will then query to the database or in the case of a mutation, use the information provided back to the client from the server as defined in
Relay will use the above returned Fleet object to tell React that the value of the component’s initial props have changed in which case the standard React method componentWillReceiveProps()
will be called as is defined,
In summary, when a user clicks to create a new FoodTruck
, React passes the information from the form to a Relay mutation object CreateFoodTruckMutation
which sends a POST
request to /graphql
, upon which a bunch of whatever code we care about on the server runs (as defined in create_order_mutation.rb
). Once the write has occured, the server sends information back to the client, that the client has been instructed to deal in the function definition getConfigs()
inside the CreateFoodTruckMutation
object which our React app then gets a call to componentWillReceiveProps(args)
inside index.jsx
at which point, our DOM updates with ONLY the new FoodTruck
.
You, the reader, have now seen the full cycle of a Mutation
. I’ve probably ommited small micro-details that you might uncover in your own quest to utilize mutations but for sure, you should now have a high level understanding of what is happening that in conjunction with the source code can be used to quickly build whatever app you care about.
Creating an Order
In the above Mutation
, we created a new FoodTruck
, for repetition’s sake, we will create an order, which adheres to the same process as above.
Notice in index.jsx
we render the React component, CreateOrder
with the function this.createOrder
bound to the createOrder
property.
When the CreateOrder
component calls this.createOrder
a CreateOrderMutation
will be instantiated and used to send information to the server.
The above CreateOrderMutation
will send food_truck_id
and tasty_item
to the server.
The mutation which specifically runs the below to create a new Order
object, save it and then send all the relevant information back to the client.
Once the server sends some json
back to the client, Relay uses getConfigs()
as defined in create_order.jsx
to tell the Relay data store that the food_truck
of id this.props.food_truck_id
has changed.
Once Relay registers that the food_truck
of id this.props.food_truck_id
has changed, React will receive a call to componentWillReceiveProps(args)
and subsequently call this.updateTruckInfo(args)
in order to allow React to update the DOM with new information.
In summary, we know have two examples of creating information that starts on the client, hits the server and then heads back to the client. There is also code in the application that demonstrates how to delete a FoodTruck
or Order
.
Delete FoodTruck
Delete Order
In Closing
Mutations and the code to get them to work is a bit slippery. When in doubt, look at and run the source code using log statements to highlight any and all underlying bits of information as needed.