Photo by Kevin Ku Table of Contents (this post) Part I: Setup and displaying short URLs using GraphQL Part II: Creating short URLs Part III: Creating serverless function for hashing Part IV: Short URL stats (number of clicks, etc.) Part V: User authentication Part I: Setup and displaying short URLs using GraphQL In this series of post I’ll explain how to build a simple URL shortener using , and GraphQL ( ). GitHub repo the project is located . React Apollo Graphcool here The idea behind the URL shortener is simple — the shortener takes a long URL such as and shortens it to When shortened URL is accessed, the service expands it to the original URL and redirects you there. The algorithm I’ll use to calculate the hash (short URL) is explained . www.example.com/thisisalongurl http://goo.gl/ABC. here Here are some of the bigger areas and features we will implement: Setup and displaying short URLs using GraphQL (this post) Creating short URLs Short URL stats (number of clicks, etc.) Expiring the URLs (e.g. no clicks in X weeks/months/years) User authentication Technologies used We are going to use and on the frontend and on the backend. React Apollo Graphcool Prerequisites Here are the prerequisites and tools I’ll be using to work on this project: (Install with: ) create-react-app npm install -g create-react-app CLI (sign up then run to install the CLI) Graphcool here npm install -g graphcool VS Code Once you have everything, we can get started with our project! Creating the project I’ll name this project as I am not too good with naming things. It doesn’t matter what you name it, I just want to make sure that if you see that name anywhere throughout the tutorial, you know what I am referring to. Shortly Open your terminal in your projects folder and start by running to scaffold a new React website: create-react-app $ create-react-app shortly I am not going to worry too much about styling, but in case I decide to add some CSS later, I’ll probably use the library. You can add the link tag to the file: Tachyons /public/index.html <link rel="stylesheet" href="https://unpkg.com/tachyons/css/tachyons.min.css"> To make sure all went well, go inside the folder an run — if all is good, you should see the default React website open in your default browser. yarn start Default React website Setting up GraphQL I am using the Graphcool CLI to set up and initialize the GraphQL project. The initialization command creates a bunch of files, so let’s create a subfolder in our root project folder first. Make sure you run before running the init command. graphcool login $ cd shortly$ mkdir graphcool && cd graphcool$ graphcool init Creating a new Graphcool service in .... ✔ Written files:├─ types.graphql├─ src│ ├─ hello.js│ └─ hello.graphql├─ graphcool.yml└─ package.json... The Graphcool CLI creates the following files: — configuration file for the Graphcool service that references your types, serverless functions and defines permissions graphcool.yml — defines the data model for your Graphcool service types.graphql folder — holds code for your serverless functions src Let’s delete the folder and remove the references to any file in that folder from the file, so the file look like this (I removed the comments as well): src graphcool.yml types: ./types.graphqlpermissions: operation: "*" Similarly, remove the type from the file and add the type we will use to store the short links. We are going to stawrt with a very simple model and add more to it later. User types.graphql Link type Link @model {id: ID! @isUniquehash: String!url: String!description: String} The definition above is pretty self-explanatory — for each link we have a unique ID, a string hash, a string URL and an optional description. If you’re wondering about what the exclamation mark on the fields those, well it makes that field required. You can read more about modelling data in Graphcool . here Finally, we need to create the actual service and push the changes we made by running the deploy command. You’d run the same command each time you make a change to your types or functions: $ graphcool deploy If you’re creating a new project, you’ll get prompted to pick a cluster where you want to deploy the service, target name ( ) and your service name ( ). prod Shortly A couple of seconds later, the CLI will give you an overview of what was added/deployed, as well as the GraphQL endpoints. We will use the Simple API endpoint in our React website to connect to the GraphQL. Setting up Apollo In this section we are going to install Apollo packages to the React website and use it to connect to the GraphQL endpoint. First, we need to install Apollo packages we’ll be using: $ yarn add apollo-client-preset react-apollo graphql-tag graphql Once that’s installed we can configure the Apollo client to connect to our GraphQL endpoint and use a to wrap the component with the . higher-order component App ApolloProvider Add import statements to : index.js import { ApolloProvider } from 'react-apollo';import { ApolloClient } from 'apollo-client';import { HttpLink } from 'apollo-link-http';import { InMemoryCache } from 'apollo-cache-inmemory' 2. Create the instance — replace the value with the one you got when you deployed the Graphcool service, or just run to show that information again. ApolloClient [SERVICE_ID] graphcool info const client = new ApolloClient({link: new HttpLink(' '),cache: new InMemoryCache(),}); https://api.graph.cool/simple/v1/ [SERVICE_ID] 3. Create a to wrap the component: higher-order component App const withApolloProvider = Comp => (<ApolloProvider client={client}>{Comp}</ApolloProvider>); ReactDOM.render( ,document.getElementById('root')); withApolloProvider(<App />) The higher-order component is a function that takes a component, wraps it inside the and returns a new component. withApolloProvider ApolloProvider Building React components Let’s add the prop-types library, so we get runtime type checking to React props. It’s a great way to ensure you’re passing correct props to your components. $ yarn add prop-types We are going to start with a and components for displaying a hardcoded (for now) array of links. Link LinkList Create the folder and a file. This file will represent a single link. src/components Link.js We are passing a single link prop to the component and displaying it inside a div. 2. Create a —this component will be used to display a list of links (at this step we use a hardcoded array of links and once we switch over to GraphQL, we will remove it) LinkList.js 3. Finally, let’s update and render the component we created: App.js LinkList Open the browser, navigate to and confirm you can see the hardcoded links. http://localhost:3000 Displaying links from an array Reading links from GraphQL In order to get the data from GraphQL we need to write a GraphQL query to fetch all links. This is the query we will be using: const ALL_LINKS_QUERY = gql`query AllLinksQuery {allLinks {idurldescriptionhash}}`; The is a helper function from and we use it to define the GraphQL query. The query was automatically generated by Graphcool and we can use it to fetch multiple nodes. The query name ( ) is our name for the query and the values inside the are the fields we want GraphQL to return. gql react-apollo allLinks AllLinksQuery allLinks Another query that is automatically generated for our type is a query. With it, we can query for a single node by id. Link For example: query SingleLink {Link (id: "someid") {urldescription}} You can read more about the Query API . here Now that we have our , we can use the container to wrap the component. When query finishes executing, the results will be in the component’s props object. Here’s the updated code in : ALL_LINKS_QUERY graphql LinkList LinkList.js Let’s explain what’s happening with the above code starting at the top. We imported and and defined the . Lines 4–16 gql graphql ALL_LINKS_QUERY We are using the loading and error properties on the query name prop to check if the data was fetch or if there was an error fetching the data. In those cases we either return a simple with “Loading” or “Error” text (these should probably be components, so you can re-use them throughout your site). If query is done loading and there’s no errors we get the data ( ) and as a final check we return a that’s say “No links…” if there aren’t any links returned. Lines 20–31 div allLinks div Using container, we are combining the component and the query. We are also specifying the name for the query ( ) that ends up being the prop name that Apollo adds to our component. Line 41 graphql allLinksQuery At this point, you can navigate to to get the No links message. Let’s use the Graphcool’s playground to add a couple of links. From the command line, run to open the playground. Alternatively, you can go to and open the playground UI from there. http://localhost:3000 graphcool playground http://graph.cool To create a new Link we are going to write GraphQL . Copy the mutation below to the Graphcool playground: mutation mutation CreateLinkMutation {createLink(description:"First link from GraphQL",url:" ",hash:"somehash") {id}} http://example.com As with the queries, Graphcool create a mutation for us — we provide the values for required fields and return an id of the created Link. Click the play button on the playground to execute the query and the mutation result should be similar to this: createLink {"data": {"createLink": {"id": "cjbr3vlnqhg1a0152fx0qpdel"} Notice how it contains the value of the id field — we could also return any other field value by simply adding a field name to the mutation. Now if you go back to the React app and refresh, you should see the Loading message first and then finally after query loads, you will see the link you created. Link from the GraphQL This is end of Part I. In the upcoming post, I will add a React component for creating new links using GraphQL mutations, implement a simple hash algorithm as a Graphcool serverless function. Thanks for Reading! You can 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