 Photo by [Kevin Ku](https://www.pexels.com/u/kevin-ku-92347/) ### Table of Contents * **Part I: Setup and displaying short URLs using GraphQL** (this post) * [Part II: Creating short URLs](https://medium.com/@pjausovec/building-url-shortener-using-react-apollo-and-graphql-part-ii-d686dd797c71) * [Part III: Creating serverless function for hashing](https://medium.com/@pjausovec/building-url-shortener-using-react-apollo-and-graphql-part-iii-6a1a74d94e5e) * [Part IV: Short URL stats (number of clicks, etc.)](https://medium.com/@pjausovec/building-url-shortener-using-react-apollo-and-graphql-part-iv-tracking-url-clicks-2d486a706008) * [Part V: User authentication](https://medium.com/@pjausovec/building-url-shortener-using-react-apollo-and-graphql-part-v-user-authentication-726c45979b82) ### **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 [**React**](https://reactjs.org/), [**Apollo**](https://www.apollographql.com/docs/react/) and GraphQL ([**Graphcool**](http://graph.cool)). GitHub repo the project is located [here](https://github.com/peterj/shortly). The idea behind the URL shortener is simple — the shortener takes a long URL such as [www.example.com/thisisalongurl](http://www.example.com/thisisalongurl) and shortens it to [http://goo.gl/ABC.](http://goo.gl/ABC.) 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 [here](https://www.kerstner.at/2012/07/shortening-strings-using-base-62-encoding/). 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 [**React**](https://reactjs.org/) and [**Apollo**](https://www.apollographql.com/docs/react/) on the frontend and [**Graphcool**](http://graph.cool) on the backend. **Prerequisites** Here are the prerequisites and tools I’ll be using to work on this project: * [create-react-app](https://github.com/facebookincubator/create-react-app) (Install with: `npm install -g create-react-app`) * [Graphcool](http://graph.cool) CLI (sign up [here](https://www.graph.cool/) then run `npm install -g graphcool` to install the CLI) * [VS Code](https://code.visualstudio.com/) Once you have everything, we can get started with our project! ### **Creating the project** I’ll name this project **Shortly** 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. Open your terminal in your projects folder and start by running `create-react-app` to scaffold a new React website: $ 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 [Tachyons](http://tachyons.io) library. You can add the link tag to the `/public/index.html` file: <link rel="stylesheet" href="https://unpkg.com/tachyons/css/tachyons.min.css"> To make sure all went well, go inside the folder an run `yarn start` — if all is good, you should see the default React website open in your default browser.  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 `graphcool login` before running the init command. $ 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: * _graphcool.yml_ — configuration file for the Graphcool service that references your types, serverless functions and defines permissions * _types.graphql_ — defines the data model for your Graphcool service * _src_ folder — holds code for your serverless functions Let’s delete the `src` folder and remove the references to any file in that folder from the `graphcool.yml` file, so the file look like this (I removed the comments as well): types: ./types.graphql permissions: - operation: "\*" Similarly, remove the `User` type from the `types.graphql` file and add the `Link` 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. type Link @model { id: ID! @isUnique hash: 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](https://www.graph.cool/docs/reference/database/data-modelling-eiroozae8u/). 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 (`prod`) and your service name (`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 [higher-order component](https://reactjs.org/docs/higher-order-components.html) to wrap the `App` component with the `ApolloProvider`. 1. 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 `ApolloClient` instance — replace the `[SERVICE_ID]` value with the one you got when you deployed the Graphcool service, or just run `graphcool info` to show that information again. const client = new ApolloClient({ link: new HttpLink('[https://api.graph.cool/simple/v1/](https://api.graph.cool/simple/v1/cjbuai6ke0dli0146amrgvg70)**\[SERVICE\_ID\]**'), cache: new InMemoryCache(), }); 3\. Create a [higher-order component](https://reactjs.org/docs/higher-order-components.html) to wrap the `App` component: **const withApolloProvider = Comp => ( <ApolloProvider client={client}>{Comp}</ApolloProvider> );** ReactDOM.render( **withApolloProvider(<App />)**, document.getElementById('root')); The higher-order component `withApolloProvider` is a function that takes a component, wraps it inside the `ApolloProvider` and returns a new component. ### **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 `Link` and `LinkList` components for displaying a hardcoded (for now) array of links. 1. Create the `src/components` folder and a `Link.js` file. This file will represent a single link. We are passing a single link prop to the component and displaying it inside a div. 2\. Create a `LinkList.js` —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) 3\. Finally, let’s update `App.js` and render the `LinkList` component we created: Open the browser, navigate to `http://localhost:3000` and confirm you can see the hardcoded links.  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 { id url description hash } }\`; The `gql` is a helper function from `react-apollo` and we use it to define the GraphQL query. The `allLinks` query was automatically generated by Graphcool and we can use it to fetch multiple nodes. The query name (`AllLinksQuery`) is our name for the query and the values inside the `allLinks` are the fields we want GraphQL to return. Another query that is automatically generated for our type is a`Link` query. With it, we can query for a single node by id. For example: query SingleLink { Link (id: "someid") { url description } } You can read more about the Query API [here](https://www.graph.cool/docs/reference/graphql-api/query-api-nia9nushae/). Now that we have our `ALL_LINKS_QUERY`, we can use the `graphql` container to wrap the `LinkList` component. When query finishes executing, the results will be in the component’s props object. Here’s the updated code in `LinkList.js` : Let’s explain what’s happening with the above code starting at the top. _Lines 4–16_ We imported `gql` and `graphql` and defined the `ALL_LINKS_QUERY`. _Lines 20–31_ 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 `div` 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 (`allLinks`) and as a final check we return a `div` that’s say “No links…” if there aren’t any links returned. _Line 41_ Using `graphql` container, we are combining the component and the query. We are also specifying the name for the query (`allLinksQuery`) that ends up being the prop name that Apollo adds to our component. At this point, you can navigate to [http://localhost:3000](http://localhost:3000) to get the No links message. Let’s use the Graphcool’s playground to add a couple of links. From the command line, run `graphcool playground` to open the playground. Alternatively, you can go to [http://graph.cool](http://graph.cool) and open the playground UI from there. To create a new Link we are going to write GraphQL [mutation](https://www.graph.cool/docs/reference/graphql-api/mutation-api-ol0yuoz6go). Copy the mutation below to the Graphcool playground: mutation CreateLinkMutation { createLink( description:"First link from GraphQL", url:"[http://example.com](http://example.com)", hash:"somehash") { id } } As with the queries, Graphcool create a `createLink` 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: { "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 [Twitter](http://twitter.com/pjausovec) and [GitHub](http://github.com/peterj). If you liked this and want to get notified when other parts are ready, you should subscribe to [my newsletter](https://tinyletter.com/pjausovec)!