Photo by Chris Kristiansen ( ) https://unsplash.com/@chriskristiansen Table of Contents Part I: Setup and displaying short URLs using GraphQL Part II: Creating short URLs Part III: Creating serverless function for hashing (this post) Part IV: Short URL stats (number of clicks, etc.) Part V: User authentication Part III: Creating serverless function for hashing In this post we are going to take the hashing function we implemented in the previous post and move it to the . Graphcool functions Functions need to be defined in the Graphcool service definition file ( ). Graphcool supports the following function types that can be invoked either as webhooks or as managed functions: graphcool.yml Before and after operations ( **operationBefore** / **operationAfter** ) For this to work, you need to specify the operation on a model for which the function should be invoked. For example: , or . An example for when this type could be used is if we wanted to implement a feature that prevents certain users from creating more than X number of links. We could use the on and run a function that checks how many links the user already created and either throw an error or allow the creation to happen. Link.update Link.delete Link.create operationBefore Link.create Subscriptions Subscription requires a subscription query that determines when the function should be triggered (e.g. when an object is created, updated or deleted). The backing function is then executed after the mutation happens. An example of this could be if we wanted to send a welcome email each time a new user signs-up. Resolvers Resolvers are the most powerful types as they allow you to come up with a new mutation and/or query definition. We will use resolvers in one of the upcoming post where we will create a mutation for signing up and logging in users as well as a query that returns a logged in user. To be honest, we could probably use all of the options above to implement our hashing function. In short, here’s how we’d do it: Option 1: Using operationBefore/operationAfter We could use either of these two options. We would need to modify the in to remove the variable as well as make the hash field optional in the schema. Next, we’d move the function to the backend to either update the created link with a hash (if we use ) or create a hash and return it for the mutation to complete if we use . CreateLinkMutation CreateShortLink.js $hash createHash operationAfter operationBefore Option 2: Using a subscription Just like we the above option, we need to remove the variable from and write a subscription query that fires when new Link is created — we already have that query, so we could update it like this: $hash CreateLinkMutation subscription NewLinkCreatedSubscription {Link(filter: { mutation_in: [CREATED] })node {id}}} In the handler function, we’d get the data returned from the subscription ( ), next we’d get the count of all links, create a hash and finally update the existing Link with this mutation: id mutation UpdateLinkWithHash($id: String!, $hash: String!) {updateLink(id: $id, hash: $hash) {id}} Option 3: Using a resolver With a resolver, we would extend our existing API with a new mutation called . The function that would be executed when this mutation is called would go through similar things as if we’d use a subscription. Function would get the number of created links, generate a hash and then return that generated hash. Then, we could call our existing CreateLinkMutation and pass in the hash we from the . createHashMutation createHashMutation Since we will use a resolver for authenticating users later, let’s use a to implement this — it is! subscription option 2 Move the hash function to subscription Follow the steps below to create a subscription and move the hashing function to the backend. Create the folder in your project root graphcool/src Add file with the following subscription that fires each time a link is created and returns its id: createShortLink.graphql subscription {Link(filter: { mutation_in: [CREATED] }) {node {id}}} 3. Add file that fires off each time a new link is created. createShortLink.js 4. Install the dependencies for subscription function by running the following command from the folder where file is: graphcool package.json $ npm install graphcool-lib --save 5. Update the to reference the graphql and js file we created: graphcool.yml functions:createShortLink:type: subscriptionquery: handler:code: src/createShortLink.graphql src/createShortLink.js 6. Deploy the changes and create the subscription: $ graphcool deploy... Subscription Functions createShortLink + A new subscription with the name `createShortLink` is created. A couple of small things before we try out the subscription: Remove function, variable from the mutation and from . Below is the updated file: createHash $hash GET_LINK_COUNT_QUERY CreateShortLink.js 2. Make the field in optional, by removing the exclamation mark: hash types.graphql type Link @model {id: ID! @isUnique url: String!description: String} hash: String Run the again to update the type and we are ready to test this out! graphcool deploy Fire up the web site ( ) if you don’t have it running already and try to create a new link — everything should work exactly like before, the only difference is that the hashing function is now being invoked as part of a subscription on the Link. To really make sure that this works, you can run to get the invocation logs from your function(s). It looks like this: yarn start graphcool logs Testing the function If there’s an error, you will also get error details in here. Second option for looking at the logs and function invocations is to go to the , click on the and then on the function to get all the logs. http://graph.cool Functions createShortLink Function overview on Graph.cool Another helpful command for testing the functions is the command from the CLI. Instead of going through our web site to create new links, we can directly send a JSON payload to the function like this: graphcool invoke-local $ graphcool invoke-local --function createShortLink --json event.json Where can look like this: event.json {"data": {"Link": {"node": {"id": "LINK_ID"}}}} This way you can test your function for bunch of scenarios that might be hard to test through the web site — e.g. invalid payloads, non-existent link IDs, etc. Coming up In the next post of the series we will work on getting some short URL stats — number of clicks. In order to do that, we will have to come up with a handler for links. For example: if we generate hash “ABC123”, we will need to write some code that’s going to execute when user visits “http://localhost:3000/ABC123” and translate that hash to an actual link and redirect the user to it. Once we have the handler we can start collecting click stats. Thanks for Reading! Any feedback on these series is more than welcome! You can also follow me on and . If you liked this and want to get notified when other parts are ready, you should subscribe to ! Twitter GitHub my newsletter