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:
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
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.
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]
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]
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:
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:
Dynamic search bar
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:
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:
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
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 !