{"id":4221,"date":"2024-12-13T10:58:38","date_gmt":"2024-12-13T10:58:38","guid":{"rendered":"https:\/\/www.rcvtechnologies.com\/blog\/?p=4221"},"modified":"2024-12-13T11:14:23","modified_gmt":"2024-12-13T11:14:23","slug":"building-a-full-stack-application-with-next-js-api-routes","status":"publish","type":"post","link":"https:\/\/www.rcvtechnologies.com\/blog\/building-a-full-stack-application-with-next-js-api-routes\/","title":{"rendered":"Building a Full-Stack Application with Next.js API Routes"},"content":{"rendered":"<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">\u00a0<\/span><span style=\"font-weight: 400;\">Introduction<\/span><\/li>\n<\/ul>\n<p><span style=\"font-weight: 400;\">Next.js is widely known for its powerful capabilities in building static websites, but its ability to handle server-side logic through API routes makes it a perfect candidate for full-stack development. In this blog, we&#8217;ll explore how to build a full-stack application using Next.js API routes. You&#8217;ll learn how to:<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Set up a Next.js project.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Create backend API endpoints using Next.js API routes.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Use these API routes to handle tasks like form submissions, data fetching, and authentication.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Deploy the entire app to Vercel.<\/span><\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Why Choose Next.js for Full-Stack Development?<\/span>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"2\"><b>Full-Stack Capabilities<\/b><span style=\"font-weight: 400;\">: Next.js allows you to build both frontend (React) and backend (API Routes) within the same project. This makes it simpler to manage code and deploy applications.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"2\"><b>API Routes<\/b><span style=\"font-weight: 400;\">: Next.js API Routes let you create backend endpoints directly in your Next.js project without needing a separate server (like Express or Fastify). This keeps your stack unified and easy to manage.<\/span><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Step-by-Step Guide to Building a Full-Stack Application with Next.js API Routes<\/span>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"2\">\n<h4><b>Setting Up the Project<\/b><\/h4>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<div class=\"dm-code-snippet dark default  dm-normal-version\" style=\"background-color:#000;\" snippet-height=\"\">\n\t\t\t<div class=\"control-language\">\n                <div class=\"dm-buttons\">\n                    <div class=\"dm-buttons-left\">\n                        <div class=\"dm-button-snippet red-button\"><\/div>\n                        <div class=\"dm-button-snippet orange-button\"><\/div>\n                        <div class=\"dm-button-snippet green-button\"><\/div>\n                    <\/div>\n                    <div class=\"dm-buttons-right\">\n                        <a id=\"dm-copy-raw-code\">\n                        <span class=\"dm-copy-text\">Copy Code<\/span>\n                        <span class=\"dm-copy-confirmed\" style=\"display:none\">Copied<\/span>\n                        <span class=\"dm-error-message\" style=\"display:none\">Use a different Browser<\/span><\/a>\n                    <\/div>\n                <\/div>\n                <pre class=\"no-line-numbers\"><code id=\"dm-code-raw\" class=\"no-wrap language-javascript\"><\/p>\n<pre class=\"dm-pre-admin-side\">npx create-next-app@latest full-stack-app<\/pre>\n<p><\/code><\/pre>\n\t\t\t<\/div>\n        <\/div>\n<p><span style=\"font-weight: 400;\">cd full-stack-app<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Creating the API Route<\/span>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"2\"><span style=\"font-weight: 400;\">Next.js makes it incredibly easy to create server-side functionality with its API routes. API routes are created inside the <\/span><span style=\"font-weight: 400;\">pages\/api<\/span><span style=\"font-weight: 400;\"> directory and can handle different HTTP methods such as GET, POST, PUT, DELETE, etc.<\/span><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<div class=\"dm-code-snippet dark default  dm-normal-version\" style=\"background-color:#000;\" snippet-height=\"\">\n\t\t\t<div class=\"control-language\">\n                <div class=\"dm-buttons\">\n                    <div class=\"dm-buttons-left\">\n                        <div class=\"dm-button-snippet red-button\"><\/div>\n                        <div class=\"dm-button-snippet orange-button\"><\/div>\n                        <div class=\"dm-button-snippet green-button\"><\/div>\n                    <\/div>\n                    <div class=\"dm-buttons-right\">\n                        <a id=\"dm-copy-raw-code\">\n                        <span class=\"dm-copy-text\">Copy Code<\/span>\n                        <span class=\"dm-copy-confirmed\" style=\"display:none\">Copied<\/span>\n                        <span class=\"dm-error-message\" style=\"display:none\">Use a different Browser<\/span><\/a>\n                    <\/div>\n                <\/div>\n                <pre class=\"no-line-numbers\"><code id=\"dm-code-raw\" class=\"no-wrap language-javascript\"><\/p>\n<pre class=\"dm-pre-admin-side\">export default async function handler(req, res) {\r\n\r\n\u00a0\u00a0if (req.method === 'POST') {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\/\/ Extract data from the request body\r\n\r\n\u00a0\u00a0\u00a0\u00a0const { name, email } = req.body;\r\n\r\n\r\n\r\n\r\n\u00a0\u00a0\u00a0\u00a0\/\/ Log the data (In a real app, you'd store it in a database)\r\n\r\n\u00a0\u00a0\u00a0\u00a0console.log('Received form submission:', { name, email });\r\n\r\n\r\n\r\n\r\n\u00a0\u00a0\u00a0\u00a0\/\/ Send a success response\r\n\r\n\u00a0\u00a0\u00a0\u00a0return res.status(200).json({ message: 'Form submitted successfully!' });\r\n\r\n\u00a0\u00a0}\r\n\r\n\r\n\r\n\r\n\u00a0\u00a0\/\/ Handle any non-POST request\r\n\r\n\u00a0\u00a0res.status(405).json({ message: 'Method Not Allowed' });\r\n\r\n}<\/pre>\n<p><\/code><\/pre>\n\t\t\t<\/div>\n        <\/div>\n<h3><b>Explanation:<\/b><\/h3>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>req<\/b><span style=\"font-weight: 400;\">: This is the request object, containing the data sent from the client.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>res<\/b><span style=\"font-weight: 400;\">: This is the response object, which will be sent back to the client.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>req.method<\/b><span style=\"font-weight: 400;\">: We check if the request is a <\/span><span style=\"font-weight: 400;\">POST<\/span><span style=\"font-weight: 400;\"> request to handle form submissions<\/span><\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Building the Front-End Form<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\"><span style=\"font-weight: 400;\"><div class=\"dm-code-snippet dark default  dm-normal-version\" style=\"background-color:#000;\" snippet-height=\"\">\n\t\t\t<div class=\"control-language\">\n                <div class=\"dm-buttons\">\n                    <div class=\"dm-buttons-left\">\n                        <div class=\"dm-button-snippet red-button\"><\/div>\n                        <div class=\"dm-button-snippet orange-button\"><\/div>\n                        <div class=\"dm-button-snippet green-button\"><\/div>\n                    <\/div>\n                    <div class=\"dm-buttons-right\">\n                        <a id=\"dm-copy-raw-code\">\n                        <span class=\"dm-copy-text\">Copy Code<\/span>\n                        <span class=\"dm-copy-confirmed\" style=\"display:none\">Copied<\/span>\n                        <span class=\"dm-error-message\" style=\"display:none\">Use a different Browser<\/span><\/a>\n                    <\/div>\n                <\/div>\n                <pre class=\"no-line-numbers\"><code id=\"dm-code-raw\" class=\"no-wrap language-javascript\"><\/span><\/span>\n<pre class=\"dm-pre-admin-side\">import { useState } from 'react';\r\n\r\nexport default function Home() {\r\n\r\n\u00a0\u00a0const [name, setName] = useState('');\r\n\r\n\u00a0\u00a0const [email, setEmail] = useState('');\r\n\r\n\u00a0\u00a0const [message, setMessage] = useState('');\r\n\r\n\r\n\r\n\r\n\u00a0\u00a0const handleSubmit = async (e) =&gt; {\r\n\r\n\u00a0\u00a0\u00a0\u00a0e.preventDefault();\r\n\r\n\r\n\r\n\r\n\u00a0\u00a0\u00a0\u00a0const response = await fetch('\/api\/submit', {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0method: 'POST',\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0headers: {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0'Content-Type': 'application\/json',\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0},\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0body: JSON.stringify({ name, email }),\r\n\r\n\u00a0\u00a0\u00a0\u00a0});\r\n\r\n\r\n\r\n\r\n\u00a0\u00a0\u00a0\u00a0const data = await response.json();\r\n\r\n\r\n\r\n\r\n\u00a0\u00a0\u00a0\u00a0if (response.ok) {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0setMessage('Form submitted successfully!');\r\n\r\n\u00a0\u00a0\u00a0\u00a0} else {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0setMessage('Something went wrong. Please try again.');\r\n\r\n\u00a0\u00a0\u00a0\u00a0}\r\n\r\n\u00a0\u00a0};\r\n\r\n\r\n\r\n\r\n\u00a0\u00a0return (\r\n\r\n\u00a0\u00a0\u00a0\u00a0&lt;div&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;h1&gt;Submit Your Details&lt;\/h1&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;form onSubmit={handleSubmit}&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;label htmlFor=\"name\"&gt;Name:&lt;\/label&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;input\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0type=\"text\"\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0id=\"name\"\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0value={name}\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0onChange={(e) =&gt; setName(e.target.value)}\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0required\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;label htmlFor=\"email\"&gt;Email:&lt;\/label&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;input\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0type=\"email\"\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0id=\"email\"\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0value={email}\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0onChange={(e) =&gt; setEmail(e.target.value)}\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0required\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;button type=\"submit\"&gt;Submit&lt;\/button&gt;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/form&gt;\r\n\r\n\r\n\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{message &amp;&amp; &lt;p&gt;{message}&lt;\/p&gt;}\r\n\r\n\u00a0\u00a0\u00a0\u00a0&lt;\/div&gt;\r\n\r\n\u00a0\u00a0);\r\n\r\n}\r\n\r\n\r\n<\/pre>\n<p><span style=\"font-weight: 400;\"><\/code><\/pre>\n\t\t\t<\/div>\n        <\/div>Connecting the Front-End and Back-End<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"2\"><span style=\"font-weight: 400;\">A form on the front-end where users can input their data.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"2\"><span style=\"font-weight: 400;\">An API route on the back-end to handle the data.<\/span><\/li>\n<\/ul>\n<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Testing the Full-Stack App<\/span>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"2\"><b>Check the Console<\/b><span style=\"font-weight: 400;\">: After submitting the form, open the terminal where you&#8217;re running your development server. You should see the data logged there:<\/span><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<div class=\"dm-code-snippet dark default  dm-normal-version\" style=\"background-color:#000;\" snippet-height=\"\">\n\t\t\t<div class=\"control-language\">\n                <div class=\"dm-buttons\">\n                    <div class=\"dm-buttons-left\">\n                        <div class=\"dm-button-snippet red-button\"><\/div>\n                        <div class=\"dm-button-snippet orange-button\"><\/div>\n                        <div class=\"dm-button-snippet green-button\"><\/div>\n                    <\/div>\n                    <div class=\"dm-buttons-right\">\n                        <a id=\"dm-copy-raw-code\">\n                        <span class=\"dm-copy-text\">Copy Code<\/span>\n                        <span class=\"dm-copy-confirmed\" style=\"display:none\">Copied<\/span>\n                        <span class=\"dm-error-message\" style=\"display:none\">Use a different Browser<\/span><\/a>\n                    <\/div>\n                <\/div>\n                <pre class=\"no-line-numbers\"><code id=\"dm-code-raw\" class=\"no-wrap language-javascript\"><\/p>\n<pre class=\"dm-pre-admin-side\">Received form submission:\u00a0\r\n\r\n{ name: 'John Doe', email: 'johndoe@example.com' }<\/pre>\n<p><\/code><\/pre>\n\t\t\t<\/div>\n        <\/div>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Conclusion<\/span><\/li>\n<\/ul>\n<p><span style=\"font-weight: 400;\">In this blog, we built a simple full-stack application using Next.js API routes. We created a form on the front-end to capture user data, and an API route on the back-end to process and log the submitted data. This is just the beginning \u2014 you can extend this setup to integrate with databases, third-party services, authentication, and more.<\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u00a0Introduction Next.js is widely known for its powerful capabilities in building static websites, but its ability to handle server-side logic through API routes makes it a perfect candidate for full-stack development. In this blog, we&#8217;ll explore how to build a full-stack application using Next.js API routes. You&#8217;ll learn how to: Set up a Next.js project. [&hellip;]<\/p>\n","protected":false},"author":16,"featured_media":4225,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_uf_show_specific_survey":0,"_uf_disable_surveys":false,"footnotes":""},"categories":[1],"tags":[],"class_list":["post-4221","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.rcvtechnologies.com\/blog\/wp-json\/wp\/v2\/posts\/4221","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.rcvtechnologies.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.rcvtechnologies.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.rcvtechnologies.com\/blog\/wp-json\/wp\/v2\/users\/16"}],"replies":[{"embeddable":true,"href":"https:\/\/www.rcvtechnologies.com\/blog\/wp-json\/wp\/v2\/comments?post=4221"}],"version-history":[{"count":8,"href":"https:\/\/www.rcvtechnologies.com\/blog\/wp-json\/wp\/v2\/posts\/4221\/revisions"}],"predecessor-version":[{"id":4244,"href":"https:\/\/www.rcvtechnologies.com\/blog\/wp-json\/wp\/v2\/posts\/4221\/revisions\/4244"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.rcvtechnologies.com\/blog\/wp-json\/wp\/v2\/media\/4225"}],"wp:attachment":[{"href":"https:\/\/www.rcvtechnologies.com\/blog\/wp-json\/wp\/v2\/media?parent=4221"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.rcvtechnologies.com\/blog\/wp-json\/wp\/v2\/categories?post=4221"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.rcvtechnologies.com\/blog\/wp-json\/wp\/v2\/tags?post=4221"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}