Let's implement the delete shop functionality to the buttons that we've added to the shop manage page. Fauna allows you to define custom resolvers to run multiple database operations so you don't have to make multiple trips to the database.
We'll define a new mutation in our GraphQL schema that will take in a shop id and sets the @resolver
directive which will tell Fauna to create a custom resolver that we can define within Fauna.
In our Fauna database, you'll see that we have a new user generated function created. This function accepts Fauna Query Language which is the native api for interacting with Fauna. We'll perform a multi-step operation by deleting the shop and then all of the products associated with that shop.
Shadid Haque: [0:00] Let's implement delete shop functionality in our application. When we delete a shop, we would also want to delete all the products that are associated with that shop. We can do this through a custom resolver.
[0:14] Fauna's custom resolvers gives you the power to run multiple database operations with one query. This way, you don't have to make multiple round trips to your database.
[0:25] To make a custom resolver, we'll go back to our schema.graphql file. Here, we'll define a new mutation. We'll call this mutation deleteShopAndProducts. It will take in a shopId as argument and return true or false. We will add the directive @resolver to this mutation. This way, Fauna will know that this is going to be a custom resolver.
[0:55] We'll also give it a name. The name is simply the name of the function to this resolver maps to. Let's save and merge this schema. If we navigate to Functions, you'll notice a new user-defined function has been created. Notice that this function is not implemented yet. Here, we can write our custom resolver logic for this function.
[1:24] These functions are written in a functional language called Fauna Query Language or FQL, in short. You can learn more about FQL in the official documentation page. Let's go over the basics of user-defined function. Query and the Lambda keyword defines a function. Let's get rid of the Abort message.
[1:45] The first argument is the argument that we pass through our GraphQL query or mutation. Let's change this to shopId. Next, with an Equals clause, we can check if the passed-in argument is equal to 123. If it is, then we're just going to return true, and if it's not, we're just going to return false. Let's save this.
[2:11] Next, we can actually go back to our GraphQL Playground, run this mutation, pass in 123 as an argument, and we'll see that it will return true. If we pass in anything else, it will be false. I hope that gives you an idea how the resolver function is working. Now, to delete the shop and the products associated with it, we're going to use a Let clause. Let is like a JavaScript object.
[2:41] Here, we can define a shopRef key and set it as a reference to the particular shop that we want to delete, so we refer to the collection Shop. Next argument is shopId. In this case, the ID is coming from our arguments. You can learn more about these FQL keywords and functions in the official documentation page. They have a really good tutorial to get you started.
[3:11] Next, we will create another key and call it deletedShop, and we're going to run delete operation on the shopRef. Then we're going to return true from the Let. Basically, if both of these statements execute, then it is going to return true. If one of them fails, then it's going to return an exception.
[3:38] Now, if we save and run that mutation again from our GraphQL Playground, it is going to delete the shop. However, we also need to delete all the products associated with the shop. Let's go ahead and get a productRef.
[3:54] For productRef, we're going to match the index product by shop. We use the shop reference as the second argument for Match, and we wrap this with the Paginate functions. That way, it turns the set reference into an array.
[4:14] Next, we're going to loop over each element of this product array and delete each product. To do this, we're going to use a Map function. The first argument in the Map function would be the array itself, so the resulting array, the productRef in our case.
[4:34] The second argument is the Lambda expression. We're going to perform the delete operation on each element. Let's save this. We're going to perform this mutation with a shop that has a couple product associated with it. If you go to the collections here, I created one shop and two products that belongs to that shop.
[5:02] Let's copy the ID of the shop. Go to our GraphQL Playground, we'll execute the delete shop and product mutation with the ID of the shop that we just copied. Now, if we go back to our collection, we'll see that all of the records are gone, so it's working as expected.
[5:27] Finally, we have to give our AuthRole permission to call this function. We're going to go to security, roles and into our AuthRole and provide permission to call this function. We will also provide read permission to product by shop index.