Backendless Coin Price List with GraphQL API, Serverless Redis and Next.JS
Tags: serverless, graphql, redis, nextjs
Published: 2021-04-20 18:16:59


In this tutorial, we will develop a simple coin price list using GraphQL API of Upstash. You can call the application `backendless` because we will access the database directly from the client (javascript).
See the [code](https://github.com/upstash/examples/tree/master/coin-price-list).

<img src="https://docs.upstash.com/img/coin-price-list/coin-price-list.png" width="800" />
    

## Motivation
We want to give a use case where you can use the GraphQL API without any backend code. The use case is publicly available read only data for web applications where you need low latency. The data is updated frequently by another backend application, you want your users to see the last updated data. Examples: Leaderboards, news list, blog list, product list, top N items in the homepages. 

### `1` Project Setup:
Create a Next application: `npx create-next-app`.

Install Apollo GraphQL client: `npm i @apollo/client`


### `2` Database Setup

If you do not have one, create a database following this [guide](overall/getstarted.md).
Connect your database via Redis CLI and run:
```shell
rpush coins '{ "name" : "Bitcoin", "price": 56819, "image": "https://s2.coinmarketcap.com/static/img/coins/64x64/1.png"}' '{ "name" : "Ethereum", "price": 2130, "image": "https://s2.coinmarketcap.com/static/img/coins/64x64/1027.png"}' '{ "name" : "Cardano", "price": 1.2, "image": "https://s2.coinmarketcap.com/static/img/coins/64x64/2010.png"}' '{ "name" : "Polkadot", "price": 35.96, "image": "https://s2.coinmarketcap.com/static/img/coins/64x64/6636.png"}' '{ "name" : "Stellar", "price": 0.506, "image": "https://s2.coinmarketcap.com/static/img/coins/64x64/512.png"}'
```

### `3` Code
In the Upstash console, copy the read only access key in your API configuration page (GraphQL Explorer > Configure API). In the `_app.js` create the Apollo client and replace the your access key as below:

:::caution
You need to use Read Only Access Key, because the key will be accessible publicly. 
:::

```javascript
import '../styles/globals.css'
import {
  ApolloClient,
  ApolloProvider, createHttpLink, InMemoryCache,
} from "@apollo/client";

const link = createHttpLink({
  uri: "https://graphql-us-east-1.upstash.io/",
  headers: {
    Authorization: "Bearer YOUR_ACCESS_TOKEN",
  },
});
const client = new ApolloClient({
  uri: "https://graphql-us-east-1.upstash.io/",
  cache: new InMemoryCache(),
  link,
});

function MyApp({ Component, pageProps }) {
  return <ApolloProvider client={client}><Component {...pageProps} /> </ApolloProvider>
}

export default MyApp
```

Edit `index.js` as below:

```javascript
import Head from 'next/head'
import styles from '../styles/Home.module.css'
import {
    gql, useQuery,
} from "@apollo/client";
import React from "react";


const GET_COIN_LIST = gql`
    query {
        redisLRange(key : "coins", start: 0, stop: 6)
    }
`;

export default function Home() {
    let coins = []
    const {loading, error, data} = useQuery(GET_COIN_LIST);

    if (!loading && !error) {
        for(let x of data.redisLRange) {
            let dd = JSON.parse(x);
            coins.push(dd)
        }
    }

    return (
        <div className={styles.container}>
            <Head>
                <title>Create Next App</title>
                <link rel="icon" href="/favicon.ico"/>
            </Head>

            <main className={styles.main}>
                <h3 className={styles.title}>
                    Coin Price List
                </h3>

                <div className={styles.grid}>
                    <table className={styles.coins}>
                        <tbody>
                        {!loading ? (
                            coins.map((item, ind) => (
                                <tr key={ind}>
                                    <td>
                                        <img src={item.image}
                                             width="25"/>
                                    </td>
                                    <td>
                                        {item.name}
                                    </td>
                                    <td className={styles.price}>
                                        ${item.price}
                                    </td>
                                </tr>
                            ))
                        ) : (
                            <tr>
                                <td>
                                    <img src="/loader.gif"/>
                                </td>
                            </tr>
                        )}
                        </tbody>
                    </table>

                </div>
            </main>

            <footer className={styles.footer}>
                <p className={styles.description}>
                    <a href="https://docs.upstash.com"> Click for the tutorial </a>
                </p>

            </footer>
        </div>
    )
}
```


### `4` Run
Run your application locally:
`npm run dev`



### `5` Live!
Go to [http://localhost:3000/](http://localhost:3000/) 🎉