Basics of GraphQL in Ruby on Rails - Changing Data | Alex Deva | Skillshare

Basics of GraphQL in Ruby on Rails - Changing Data

Alex Deva

Play Speed
  • 0.5x
  • 1x (Normal)
  • 1.25x
  • 1.5x
  • 2x
8 Lessons (20m)
    • 1. What we'll do

    • 2. Creating records

    • 3. Query variables

    • 4. Input types

    • 5. Updating records

    • 6. Deleting records

    • 7. Handling validation errors

    • 8. Assignment 2


About This Class

This course teaches the basics of using GraphQL in a Rails application. GraphQL is a query language invented by Facebook in 2012, and made open source in 2015. While it has certain clear advantages over REST, it also has a somewhat steeper learning curve.

Structured in a simple and accessible manner, these lectures will help you get on your way to using GraphQL to circulate data between back-end and front-end applications.

After an introductory class, in the next class we will learn about reading data; in the third, about changing data; and the slightly more advanced fourth class is about protecting data.

This is the third class: changing data.


1. What we'll do: hello and welcome to a new section of the school's. So far, we've been learning how to read data from the back and sending it to the front end in this section. However, we're going to learn how to change data. Ah, now another word that change is mutate. And that's why the particular queries that changed eight on the back and are cold mutation invitations. Mutation looks like this. It has the key. What mutation? As the beginning. And then the field has several arguments, which makes sense because you want to pass that are from the front into the baby back and and telling it how you want things changed under what in your data should be. Perhaps, And then you have field selectors like, in this case stars, which work exactly like in a regular query, which tell the back and hard to answer. And on the on the ruby side Ah, this mutation looks like this is it's ah, it's an object of the type mutation type on. It has a field just like a regular query, and all the arguments are risk listed individually, and this one is a mutation that rates opposed, possibly a block post it rates it by incriminating or by giving it a specific amount of stars. Now for that, it takes two arguments. 11 is the entity far the post, and the other one is the count of stars that oppose will have in the result block. We find the Post, we write the post and then we return the post because The Post has an attribute called Cold Stars. It's going to be referred, uh, as, um, as a return field, just no justice in the regular query in this section we're going to we're going to work with creating, updating, deleting and handling validation errors. Onda, um, we're going to start with the creation in the next lecture. 2. Creating records: data is changed via mutations, which are a special type of queries. There are two ways to create mutations on they both start in this fall Mutation type thought RV inside the types directory. First of all, we're going to remove the test field because we don't need anymore. No, we're going to create ah, simple Field, which we're going to call create author Onda. We're going to add a resolver method to it on a side effect of this result. A method will be that it creates an author in the database. The field will look like this. So this is the field, as you can see, has a name, it has a type. It's going to return The author that was created, it's allowed to be null, and it has a description. We're going to give it the block and inside this block, we're going. Teoh enumerates the arguments required to create an author. As you can see, I've used caramelize falls for all the, uh for all the fields that might have otherwise be turning to come in case just so that we can keep it a little more consistent. Um, if you're use front end where camera case is compulsory only after deal is not specify deception. So we've entered the four attributes which together make unauthorized. Now all we need to do is resolve this field with a method that, as a side effect, as I've said, would create another based on these arguments. And there we have it. We have a mutation field which has a name create author, and it will return. Ah, created author once it's once was created as a side effect of running, it's ah result for method. Want to try this method? We switch over to graphic UAL and this is how you write a mutation. A mutation always starts with imitation keyword, and they would give the name and the arguments because this mutation, this field will also return another. We have to use selectors in order to see what we've um created on will just settle for an I . D. On the full name of the created author. You run this, we'll see that it's created an author with the idea of four which was the next available i d. If we reload graphical so that we can have a look at the documentation inside the mutation we can see that there's a create author mutation which takes these for parameters on that it creates an author, which is exactly how we've described it. Now. The second way to create imitation is to leave the field in mutation type, but delegate the resolution of the field to a separate file and just going to comment out this this gold on. I'm going to write a new field here, and I'm going to say that it's going to use a mutation which will create in a moment on DA . It's going to live in the name space mutations with the name create author in San Mutations . We're going to create this mutation file this class inherit from gruff Kyul schema mutation . But we might as well go the same route as with queries and use a based object to inherit from what we don't need necessarily need to. And in this class we would define this particular and specific mutation. I would say that Ah, it may be no, it has a number of arguments, which I'm just going to copy here on finally have a result method and in that method create the date of his record right, So let's see if this works equally well. We're just going to create a copy of an ascending way on. It worked just a swell. So to recap, we can either create a regular field and do the mutation to the code actually change data in its results method right inside the mutation type. Or we can just leave the field here. And perhaps if there's a little more work, we can delegate limitation to a different to a separate file, which will leave in the Mutations directory, and that's what the Mutations directory is for. 3. Query variables: it is often inconvenient from the perspective of the front end to mix code and data like we did in this mutation. It is often the case that queries or mutations are saved in one place in the front end on they are expected to work with any kind of data from any source possible. So for that purpose graphic UAL introduced the concept of variables query variables. In order to separate the query from its data, we can separate the letter into variables. Now. The way to work very boots into a mutation is to add into the definition of the mutation here, the name of the mutation again on list all the variables that we're going to need with a dollar in front of them and the type after that, Having done this instead of providing the values here, we just refer to the variables, and we populate the query variables in the form of a simple Jason structure. And with that graphic, you'll is going to send both Macquarie on. The variables have spotted the same http request, and the effect is going to be the same. We've created the record where, instead of specifying the data as part of the query, we've separated it into adjacent structure in the form of query variables 4. Input types: no one problem that's immediately clear. When we write mutations like this, the question arises. What happens if the back and changes theatric buttes of a database record? For instance, what happens if we add two or three or seven or 10 more attributes to an author? Then we have to repeat these two or three or 10 attributes, one to potentially three different times. So would it not be nice to be able to group all of the attributes of a North ER in one single structure? And that is called an input type? So ideally, what you want right here in the query in the front end would be just to have one simple author structure that would contain all the other fields all the relevant fields on the necessary fields. And this would have the type, which for now, we'll call author input type, and this would be a non unknowable feel. The required field, and we would signify that by graphic UAL convention by adding a question mark at the end. This is a required field, so having this variable, we would pass it along as ah, the argument to create author. Instead of passing each attribute in turn, we'll just pass this and then we would group all these variables inside an author object. How would we make this work? Well, it turns out it's quite easy to create an import type using the graphic Ilja, and we could create a separate file for it here in the types directory. But for the sake of keeping things together and because there's also has to do with authors , I would add it here in the same class as the Ortho type. So this is an input type. It has a name, which is the name by which this type is seen by the front end, the name by which it appears in the graphical documentation and everything. It has a description, and I've moved all the arguments here now with the arguments here in the info type. I don't need them anymore in the mutation field. So I'm just going to replace all these arguments with one single argument. Author of the type which is going to be required and with that all way to do is change the result methods. So rather than receiving all these attributes, it just receives one object, and it creates a new author. Based on that object, we have to convert it into a hash to conform with raises conventions. So now if you try this, it suddenly works. And we have a new author, the same Scott Lynch well duplicated with another idea we can easily at Stephen King here I was born, I think, in 1947 on it will work just as well. So all the agile, all the attributes are in the query variables. The query doesn't need to know any longer what each and every attribute of another is. And if you look in the dogs, we'll see that the Creator author field now has only one argument of the type or three input type, which has all the attributes here. And this makes it a lot easier and a lot more consistent. Teoh Avoid make me stakes when editing the changing or adding or deleting the attributes of an active record object so that you don't need to communicate this every time to the front end 5. Updating records: in this lecture, we're going to learn how to update existing records in the database. Now, with our current knowledge, this is pretty straightforward. The only thing that we need to pay attention to is that we need to know which record we are updating. And there are many ways to pass the idea of a record. I find that the most convenient one from the perspective of the front end is to added as a non argument, together with all the other arguments that are required to changing object will make it not necessarily required so that we can also use it. To create your stuff on the mutation is pretty straightforward When updating a record, it's not necessarily usually to return the actual record because the front and knows what the changes were. Rather, it surfaces. Teoh return a true or false value to signify whether the operation function or not. And we're going to resolve this field, and assuming we found his extinct record, we're going to try to update it, and that's it. The query to update a record would be very similar to the one to create it, except it won't we won't be needing these two selectors because this is a bullion query on it will only return true or false. So if we not take, um the author with the idea of nine I think was different king and we make him 100 years older, we get, ah, return of true. And if you really want to make sure that that happened, we can look in the application logs and see the update query here where we updated the year to 18. 47. Think it makes sense to add it back at the 100 years back? Onda Gennett work. So this is how we create a mutation to update existing records in the database using graphic you well. 6. Deleting records: with the knowledge we've accumulated so far, learning how to delete a record seems pretty easy and just going to create a new mutation field again. We're going to use a bullion type, and all we need to delete an author is the record I d having that. We can just resolve the field and phenolic and just return true for all cases. And the credit to the little author is again easy. In this case, we won't necessarily need variables. So we can just past the i d here. Andi, I think we have deleted the author that didn't have a first name or last name. There you go. And this is how we can delete records from the database using graphical. 7. Handling validation errors: the question arises. What happens when something goes wrong? How do we handle, for instance, validation errors when creating another? Well, there's no default mechanism as of this time in the graft, your job. There's a suggestion in the graphical documentation, but that involves duplicating the error signaling mechanism across all the models. My suggestion is a lot simpler. We create an error type, and we make it fit the errors, the validation errors that active records has. Anyway. First of all, we're going to do something that would cause such never to appear. So we're going to open the author model and at a validation role to it. And let's say we make the last name compulsory. There you go. So now we can't savor North without the last name anymore. And now we have another field to the author type, which we call letters, and this will have a type that we will define a second. But because you can have more than one validation, arrows at the time will make it on. The array of such objects obviously can be gnarly. Hopefully, should be no most of the time, and now we resolve it. So, given an object that has ADDers. We can map every letter into a hush that has field name and the errors on that field name, right? So what about this other type, which right now Ruby underlines because it's not defined? What we want is to turn the errors that active record provides into something that looks good on Graphic UL. So we're going to create this new type, and again, it's, ah, simple class, and it's going to have to fields on a Zaev said for a given field name. We could have several errors, so this was this will be on array of strings. So what happens here if we create an author that has enters, Um, we're going to return this field errors in which we cost all the errors into the type at a type. And we do that by turning the arrows into Honore and for each element of the array. So for each element that has the other type, so this big type on it, we have a field name on a list of errors for it. So if you try to create an author doesn't have a last name on, we add the errors selector with its own to select us into the query. We're going to get back a message saying that the last name can't be blank, and I think this is a clean and nice and relatively easy way to propagate active record errors into the front end using graphical. 8. Assignment 2: And now it's time to continue your work on the homework you did in the previous section for this section of going to extend the beckoned you've done, you've started working on for a blawg on. What we will do is to create, create, update and delete mutations for the three models that you have there in the application on . You have to do that using input types and query variables, which is the easiest way. And please also add at least one validation rules to at least one of the models and make sure that you check for errors when you try everything in graphic will. That's it. Good luck.