Leverage data from RapidApi using Redux Toolkit

Leverage data from RapidApi using Redux Toolkit

API (Application Programming Interface) is a set of programming codes that enables data communication between one software product and another. It is a messenger that takes a request and tells the system what to do. JSON and XML are the most common format of data provided in the response.

In this tutorial, you will learn how to use Redux Toolkit but also how to use its RTK query feature to fetch data from an API. We will fetch data using RapidAPI, and build a simple app. To follow this tutorial, you'll need knowledge of JavaScript and React, and a Rapid API account.

About our tools

Our data source, RapidAPI, is one of the world's largest API Marketplaces and is used by developers to discover, search, test, and connect to thousands of public APIs. It offers more than 30,000 APIs, supports multiple API types, and provides code snippets, documentation, and even tooling needed to integrate easily using a single SDK, API key, and dashboard.

Our state management tool, Redux Toolkit, is a simple, opinionated, powerful, and effective state management library that allows developers to write efficient code, catch errors, speed up the development process, and apply best-recommended practices. Redux Toolkit (or RTK) is designed to solve some of the problems in Redux:

  • The hassle of configuring a store.
  • The need for installation of additional tools to get all of the applications you need.
  • All the boilerplate and unnecessary code that makes it unmanageable to write efficient and clean code.

Read more about the features the Redux toolkit offers from their official docs.

Finally, RTK Query is an optional add-on within the @reduxjs/toolkit package. According to the documentation, "It is purpose-built to solve the use case of data fetching and caching, supplying a compact but powerful toolset to define an API interface layer for your app. It is intended to simplify common cases for loading data in a web application, eliminating the need to hand-write data fetching & caching logic yourself."

RTK Query makes it easy by handling the server cache, allowing us to focus solely on the UI state. RTK Query includes some cool APIs out of the box. You can check them out here. We will be using some of them to build our application. With RTK Query and a few lines of code, we can start working with cached and fetched data from RapidAPI in our React project.

Setting up our app

Let's start by creating a new React app with the commands below. We'll be setting up our project from the Chakra UI template. The templates are similar to the base create-react-app template, but they come with Chakra UI dependencies pre-installed and include Chakra-specific functionality. We'll also add Redux and the Redux Toolkit.

yarn create react-app crypto-news-site --template @chakra-ui
yarn add @reduxjs/toolkit react-redux

This will be the created structure.

image.png

Getting data from RapidAPI

Go to RapidAPI and signup for an account. Search for Bing New Search. We will be building a news site about cryptocurrency. Click on pricing and subscribe for a free plan. After subscribing, go back to the endpoint and copy your RapidAPI key. In your React app, create a .env and paste your API key as follows:

REACT_APP_RAPIDAPI_KEY = "your api key"

Now, to get data, create a file named src/services/cryptoNewApi.js.

import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';

const cryptoNewsHeader = {
    'x-bingapis-sdk': 'true',
    'x-rapidapi-host': 'bing-news-search1.p.rapidapi.com',
    'x-rapidapi-key': process.env.REACT_APP_RAPIDAPI_KEY,
};

const createRequest = (url) => ({ url, headers: cryptoNewsHeader});

export const cryptoNewsApi = createApi({
  reducerPath: 'cryptoNewsApi',
  baseQuery: fetchBaseQuery({ baseUrl: 'https://bing-news-search1.p.rapidapi.com'}),
  endpoints: (builder) => ({
    getCryptosNews: builder.query({
      query: ({newsCategory, count}) => createRequest(`/news/search?q=${newsCategory}&safeSearch=Off&textFormat=Raw&freshness=Day&count=${count}`),
    })
  })
});

This is how Redux fetches data from an API. We imported createApi and fetchBaseQuery from the Redux Toolkit.

  • createApi - The primary source of RTK Query functionality. It gives us flexible configurations on how to fetch and transform fetched data and define a set of endpoints describing how to retrieve data from a series of endpoints.

In our example, we pass on an object that defines three things:

  • reducerPath - We define a unique key where Redux will store our cache.
  • baseQuery - The base query to request data.
  • fetchBaseQuery - similar to Axios, it provides a lightweight wrapper around fetch queries, which helps simplify requests. The fetchBaseQuery accepts the baseurl, the URL we got from the RapidAPI host.
  • endpoints - sets of operations we want to perform against the server. In our case, we have only one, getCryptosNews, which we destructured to get the newsCategory and the count to query for the endpoint.

We have also created a utility function where we passed in the URL and our headers. This will help us get the specified request we are looking for from RapidAPI.

Connecting to the Redux Store

Create a file named src/app/store.js. Import the configureStore API from Redux Toolkit. We'll start by creating an empty Redux store and exporting it. This will be our central state of truth, meaning your entire application state.

import { configureStore } from '@reduxjs/toolkit';
import { cryptoNewsApi } from '../services/cryptoNewsApi';

export default configureStore({
    reducer: {
        [cryptoNewsApi.reducerPath]: cryptoNewsApi.reducer,
    },
    middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware().concat(cryptoNewsApi.middleware),

});

Connect our cryptoNewApi to the store so it can be made available to our React components. We import cryptoNewApi into our store. The API object we created with createApi has given us everything we need:

  • reducerPath and reducer, which we pass straight into the reducer parameter of configureStore.
  • middleware - allow us to take advantage of invalidation, caching, polling, and some other features of RTK Query.

To connect our React components to our project, we will go to src/index.js. We must

import the provider from react-redux and our store from app/store.js.
import { Provider } from 'react-redux';
import store from './app/store'

Then we will wrap our App with the provider with our store as a prop.

<Provider store={store}>
  <App />
</Provider>

Creating a hook to get the data for your query

To get the data for our query. Go back src/services/cryptoNewApi.js. We will export our API.

export const { useGetCryptosNewsQuery } = cryptoNewsApi;

The RTK Query will automatically generate hooks that we can call instantly for each endpoint query. This makes it so much easier to retrieve data. It also gives us loading states, finalized states, and everything we need to make API calls. In this example, useGetCryptosNewsQuery. This is done by using createApi from '@reduxjs/toolkit/query/react'.

Open Source Session Replay

OpenReplay is an open-source, session replay suite that lets you see what users do on your web app, helping you troubleshoot issues faster. OpenReplay is self-hosted for full control over your data.

image.png

Start enjoying your debugging experience - start using OpenReplay for free.

Building and Fetching the data to our frontend

In our App.js, paste the following code:

import React from 'react';
import {
    Box,
    Grid,
    Link,
    Spinner,
    Image,
    Text,
    Stack,
    Avatar,
    useColorModeValue,
    Flex,
    Heading,
    Input,
    Spacer
  } from '@chakra-ui/react';
import { useGetCryptosNewsQuery } from './services/cryptoNewsApi';

We import the components we will use to build our user interfaces from Chakra UI. We also import our useGetCryptoNewsQuery hook from ./services/cryptoNewsApi.

function App() {
  const newsCategory ='Cryptocurrency';
  const { data: cryptoNews } = useGetCryptosNewsQuery({newsCategory})
  const color = useColorModeValue('white', 'gray.900');

  if (!cryptoNews?.value) return <Spinner  />;

  return (
    <Box px={'6'} py={'16'}>
      <Flex pb={'6'}>
        <Heading>CryptoNewsSite</Heading>
        <Spacer />
        <Input htmlSize={20} width='auto' placeholder='Search for Crypto' />
      </Flex>
      <Grid templateColumns={{ md: 'repeat(3, 1fr)' }} gap={6}>
        {cryptoNews?.value.map((news, i)=>(
            <Box
            w={'full'}
            bg={color}
            boxShadow={'2xl'}
            rounded={'md'}
            p={6}
            overflow={'hidden'}
            key={i}>
              <Box
              h={'250px'}
              bg={'gray.100'}
              mt={-6}
              mx={-6}
              mb={6}
              pos={'relative'}>
              <Image 
              src={news?.image?.thumbnail?.contentUrl || demoImage} 
              layout={'fill'}
              w={'full'}
              h={'full'}
                />
              </Box>
              <Stack>
                <Link
                  href={news.url} target='_blank' rel='noreferrer'
                  color={'green.500'}
                  textTransform={'uppercase'}
                  fontWeight={800}
                  fontSize={'sm'}
                  letterSpacing={1.1}>
                  {news.name}
                </Link>
                <Text color={'gray.500'}>
                  {news.description > 100 ? `${news.description.subString(0, 100)}...` : news.description}
                </Text>
              </Stack>
              <Stack mt={6} direction={'row'} spacing={4} align={'center'}>
                <Avatar
                  src={news.provider[0]?.image?.thumbnail?.contentUrl || demoImage}
                  alt={'Author'}
                />
                <Stack direction={'column'} spacing={0} fontSize={'sm'}>
                  <Text fontWeight={600}>{news.provider[0]?.name}</Text>
                  <Text color={'gray.500'}>{new Date(news.datePublished).toLocaleDateString(undefined, {  
                      day:   'numeric',
                      month: 'short',
                      year:  'numeric',
                  })}</Text>
                </Stack>
              </Stack>
            </Box>
        ))}
      </Grid>
    </Box>
  );
}
export default App;

This is pretty straightforward; we are trying to get news about cryptocurrency so we can define it and assign it to our hook. We then used our components to style and built our UI. We now have access to our API cryptoNews and map through it to get the image, name, description, provider of the article, and date the article was published. Here is what our app looks like:

image.png

Conclusion

This article taught us how to use the RTK query to fetch data from RapidAPI into our project. We also know how to use Chakra UI in building user interfaces. I hope this article gives an insight into how to use the Redux toolkit and fetch data from Rapid API using the Redux toolkit as state management.

To take it a bit further, you can add search functionality to the app so that when a user starts typing the name of a particular cryptocurrency, a list of possible news matches will be filtered and displayed.

All codes for this article can be found on Github.