Build a React app AND your own custom REST API

Build a React app AND your own custom REST API

·

7 min read

Hello friend, in this tutorial i'll be walking you through the process of making your own REST API and how to use it on a React app!

This is the project we'll be building today:

final_62720314b01a3400605eedd0_4761

You can check the live version here

This is a bit of a long one, and I'll be with you every step of the way, so let's get started! :]

Creating our custom REST API

We'll be using json-server package to make things easier when making our API.

First, we need to create a folder with a file to hold our data; let's call it db.json.

{
    "articles": [
    {
        "id": 0,
        "title": "Write a How-To Guide",
        "language": "JavaScript",
        "description": "It can be how to make a vanilla js app or how to deploy it"
    },
    {
        "id": 1,
        "title": "Write a beginners tutorial",
        "language": "JavaScript",
        "description": "Make an app from zero to deployment targeted at code newbies"
    },
    {
        "id": 2,
        "title": "Write a Tutorial",
        "language": "Node.js",
        "description": "It can be how to set up your first server or a basic guide"
    }
]
}

We go to the directory of our app and install the package that will help us set up our API typing in our command line:

npm install json-server

Now to initialize our server all we need to do is call up the package and tell it to 'watch' our db

json-server --watch db.json

Screenshot (294)

All done!! That was quite easy, wasn't it? If we visit localhost:3000 we'll see that we can use the methods as with a normal API and we have our /articles route.

Screenshot (295)

Let's do some final touches so we're able to deploy it. Go back to our current directory using the command line and type:

npm init

because we need a bit of backend to deploy it so we can use it in our app, and now we type:

npm i json-server

so that Heroku knows we'll be using that package.

Now let's make a quick back-end making a server.js file:

const jsonServer = require('json-server');
const server = jsonServer.create();
const router = jsonServer.router('db.json');
const middlewares = jsonServer.defaults();
const port = process.env.PORT || 3000;

server.use(middlewares);
server.use(router);

server.listen(port);

And we create a new script in our package.json file that will initiate our server.js file

  "scripts": {
    "start": "node server.js"
  },

Deploying the API

Now let's deploy it using Heroku. Remember to add a .gitignore file to ignore our node_modules. You must have Git and the Heroku CLI installed to deploy with Git.

  • Create a github repo and commit the files we just made for our api
  • Sign up/ log in to heroku
  • Create a new project using heroku create
    heroku create my-articles-api
    
  • Login again using
    heroku login
    
  • Create your project
    heroku create article-api-inspiration
    
  • Push what we just did to Heroku
    git push heroku main
    

And now we have deployed our API and can use it on our app!!

You can check all the files for our API in the repo

Setting up our REACT environment

We'll start by creating a new React app, to do this go to your Command Line and cd over to a new folder, the folder you're going to create your application and type npx-create-react-app [your app name] and hit enter, this will work if you have Node >= 14.0.0 y npm >= 5.6.

cd Desktop => cd [app folder] => npx create-react-app [your app name]

If that doesn't work type "npm init" this will create a file package. json and then type npx-create-react-app [your app name]

Screenshot (296)

If you were succesful all we need to do is cd over to our app and type npm start.

cd Desktop => cd [app folder] => npm init => npx create-react-app [your app name]

Screenshot (251)

Get the styling from the App.css file in the GitHub repo

Fetching data from our custom API

Now let's work on our App.js file; we'll need to fetch the data from the API we just created. For this we'll be using the useEffect hook.

import './App.css';
import {useState, useEffect} from "react";

function App() {

  const [ideas, setIdeas] = useState([])

  useEffect(() =>{
    fetch("https://article-api-inspiration.herokuapp.com/articles")
    .then(res => res.json())
    .then(data =>{
      setIdeas(data)
    })
    .catch(err =>{
      console.log(err)
    })
  }, [])

  return (
    <div className="App">
    </div>
  );
}

export default App;

Let's console.log our data and see if everything's working how it's supposed to:

Screenshot (297)

Perfect! Now let's create a dynamic component so that every time a new article idea is submitted it will authomatically generate a new element to display it using props.

//ideaComponent.jsx

function IdeaComponent(props){
    return(
        <div className="content-container">
        <h1 className="idea-title"> {props.title}</h1>
        <p className="idea-desc">{props.description}</p>
        <h3 className="idea-lang">{props.language}</h3>
        </div>
    )
}

export default IdeaComponent;

Now let's populate our component using props in our App.js:

 return (
    <div className="App">
        {ideas.map((idea, index) => (
            <IdeaComponent
            key={index}
            id={index}
            title={idea.title}
            language={idea.language}
            description={idea.description}  
            />
        ))}
    </div>
  );

It should be looking like this:

Screenshot (298)

Let's create a dynamic search bar so that when the user enters a language it will filter out the result. We're going to need to modify our map function a bit to filter the results out and present them. We'll also need to create a new state for it.

const [query, searchQuery] = useState("")

And now let's create our input or search bar

 return (
    <div className="App">
<input 
  className="searchBar"
  placeholder="Search by language" 
  onChange={event => searchQuery(event.target.value)} />

    </div>
  );

The logic for our search bar is quite simple; we'll use the filter method to see if the query the user searches for matches a language in our ideas array, if so we'll populate it with said language. To make the comparison more accurate, we'll turn the query to lower case.

  return (

    <div className="App">

<input 
  className="searchBar"
  placeholder="Search by language" 
  onChange={event => searchQuery(event.target.value)} />

        {ideas.filter(languageQuery =>{
          if(query === ''){
            return languageQuery
          } else if (languageQuery.language.toLowerCase().includes(query.toLowerCase())){
            return languageQuery;
          }
        }).map((idea, index) => (

            <IdeaComponent
            key={index}
            id={index}
            title={idea.title}
            language={idea.language}
            description={idea.description}  
            />
        ))}
    </div>
  );

This is the functionality we're looking for:

final_6271fdb59e581e00aad88cbb_740453

MUI Library

It's looking quite rough so let's use MUI for our grid and make everything look better.

Let's go back to our command line and install the MUI library:

npm install @mui/material @emotion/react @emotion/styled

Don't forget to restart our React app with npm start and in our App.js file let's import the Box and Grid components from the MUI library.

import Box from '@mui/material/Box';
import Grid from '@mui/material/Grid';

Now we need to add a box that will hold our grid elements; feel free to play around with the MUI library and figure out if this layout is one that you really like.

In our App.js we'll add the Box and Grid components:

  return (

    <div className="App">

<input 
  className="searchBar"
  placeholder="Search by language" 
  onChange={event => searchQuery(event.target.value)} />

  <Box sx={{ flexGrow: 1 }}>

   <Grid container 
    justifyContent="center"
    alignItems="center" 
    spacing={{ xs: 4, md: 8 }} 
    columns={{ xs: 5, sm: 9, md: 10 }}> 

    {ideas.filter(languageQuery => {
      if (query === '') {
        return languageQuery;
        } else if (languageQuery.language.toLowerCase().includes(query.toLowerCase())) {
          return languageQuery;
          }}).map((idea, index) => (

            <Grid item xs={4} sm={4} md={3} key={index}>

            <IdeaComponent
            key={index}
            id={index}
            title={idea.title}
            language={idea.language}
            description={idea.description}  
            />

           </Grid>
           ))}

  </Grid>   
  </Box>

    </div>
  );

This is what we have so far:

Screenshot (299)

Yey! Almost done. Now let's add our css and create our header.jsx and footer.jsx.

//Header.jsx

function Header(){
    return(
        <div className="header">
            <h1>Technical Writing Prompts</h1>
            <p> The hardest part of writing is coming up with a concept idea, not anymore! <br />
            Enter your preferred language in the search bar bellow and find fitting writing prompts according to what you're looking.</p>
        </div>

    )
}

export default Header;
//Footer.jsx

function Footer(){
    return(
        <div className="footer">
            <h3 className="footer-txt">Made by <a href="https://twitter.com/yuricodesbot"> Yuri</a> <br />
            Have an idea you want to <a href="https://github.com/YuriCodes/article-ideas-api" target="_blank"> submit? </a></h3>

        </div>

    )
}

export default Footer;

After importing our Header and Footer to our App.js this is the result

Screenshot (292)

Yey!! You've made it!

I really hope you learned something new today and had fun while doing it. React is such a fun library to create projects with and makes rendering data easier.

You can check the source code here and the live version


Don't hesitate to contact me and let me know if you'd like to add something else in the comments.

☕If you enjoy my content Buy me a coffee It'll help me continue making quality blogs💕

💙Follow me on Twitter to know more about my self-taught journey!

💜 Web Design for Beginners Series

💜 JavaScript For Newbies Series

❤️ Also subscribe to my Youtube Channel !

🖤And for more content and tips on TikTok !