DEV Community

BK Mahapatra
BK Mahapatra

Posted on

Custom Backend Form API

Image by storyset on Freepik

Have you ever faced a scenario as a frontend developer, whether in a company or freelancing, where a client requires specific forms like contact or inquiry forms tailored to their needs? In these situations, dealing with the backend side might not be your forte, and existing third-party software costs for such standalone tasks can be quite high.๐Ÿ˜ฟ

๐Ÿ˜ŽFeel empowered to tackle tasks with confidence. I've got a simple code snippet that streamlines crafting fully customized form APIs, making the process approachable for everyone involved. No need for a traditional database setup; opt for the simplicity of Google Sheets, and you'll discover creating and managing tailored forms becomes even more accessible.

Primarily, this task has been executed using Next.js, but keep in mind that you can apply the same approach with any other framework or technology of your choice. The provided code snippet is versatile and adaptable, making it suitable for various development environments beyond Next.js.๐Ÿš€

Requirements:

  1. Google API

Process:

  1. Setup Google Cloud Account and Enable Sheet API.
  2. Configure Google Service account
  3. Download Google API Key
  4. Create a google sheet and share read , edit and modify access to the google service client Email.
  5. Replace the .env file with Your google credentials
  6. Create a Next.js project or Any simple backend instance
  7. Install required Packages (Cors and google)
  8. Paste and Modify the code as per requirement.
  9. Test and Deploy done ๐Ÿš€๐Ÿš€๐Ÿš€

Code:

  • .env
PROJECT_ID="Your Project ID"
PRIVATE_KEY="Your Private Key"
PRIVATE_KEY_ID="Your Private KeyID"
CLIENT_ID="Your Client ID"
CLIENT_EMAIL="Your Client Email"
CLIENT_CERT_URL="Your Client Cert Url"
Enter fullscreen mode Exit fullscreen mode
  • customForm.js
import { google } from "googleapis";
import Cors from "cors";

function initMiddleware(middleware) {
  return (req, res) =>
    new Promise((resolve, reject) => {
      middleware(req, res, (result) => {
        if (result instanceof Error) {
          return reject(result);
        }
        return resolve(result);
      });
    });
}

const cors = initMiddleware(
  Cors({
    origin: "*",
    methods: ["POST"],
    allowedHeaders: ["Content-Type"],
    preflightContinue: true,
  })
);

export default async function handler(req, res) {
// Respond to preflight request
  if (req.method === "OPTIONS") {
    res.status(200).end();
    return;
  }

  // for proper line breaks of line items
  const privateKeyCn = process.env.PRIVATE_KEY.replace(/\\n/g, "\n");

  const { sheetId, sheetName, rowData } = req.body;

  if (req.method == "POST") {
        //for CORS policy
    await cors(req, res);

    try {
      const auth = new google.auth.GoogleAuth({
                //google credentials
        credentials: {
          type: "service_account",
          project_id: process.env.PROJECT_ID,
          private_key_id: process.env.PRIVATE_KEY_ID,
          private_key: privateKeyCn,
          client_email: process.env.CLIENT_EMAIL,
          client_id: process.env.CLIENT_ID,
          auth_uri: "https://accounts.google.com/o/oauth2/auth",
          token_uri: "https://oauth2.googleapis.com/token",
          auth_provider_x509_cert_url:
            "https://www.googleapis.com/oauth2/v1/certs",
          client_x509_cert_url: process.env.CLIENT_CERT_URL,
          universe_domain: "googleapis.com",
        },
        scopes: ["https://www.googleapis.com/auth/spreadsheets"],
      });

      // create client instance
      const client = await auth.getClient();

      // instance of google sheets api
      const googleSheets = google.sheets({ version: "v4", auth: client });

      //  write rows
      await googleSheets.spreadsheets.values.append({
        auth: auth,
        spreadsheetId: `${sheetId}`, // sheet id of your google sheet
        range: `${sheetName}!A:A`,

        valueInputOption: "USER_ENTERED",

        insertDataOption: "INSERT_ROWS",

        resource: {
          majorDimension: "ROWS",
          range: `${sheetName}!A:A`, //In which sheet you want to populate
          values: [rowData], // format: [["John Snow", "22", "Engineer","New York",...]]
        },
      });
      res.status(200).send("success");
    } catch (e) {
      console.log(e);
      res.status(400).send(JSON.stringify(e));
    }
  }
}
Enter fullscreen mode Exit fullscreen mode
  • file.js
//calling your API end point

//....your code
const handleSubmit = async (event) => {

    event.preventDefault();

    const url = "https://www.yourWebsite.com/api/customForm"; //your api end point

    const reff = referer || "not available";
    const ipAddrs = ipAddress || "no IP";
    const date = new Date().toLocaleString();
    const name = userData?.fullName?.trim() || "";
    const phone = userData?.phone || "";
    const email = userData?.email || "";
    const msg = userData?.msg || "";

        //you can add fields are per the requirements there is no need to change in the backend
    const bodyContent = {
      sheetId: "Your Sheet ID",
      sheetName: `${Your Sheet Name}`,
      rowData: [
        date, //submission date
        ipAddrs, //IP Address of user
        currentURL, // in which page form get submitted
        reffer, //source
        name,
        phone,
        email,
        msg,
      ],
    };
    try {
      const response = await axios.post(url, bodyContent, {
        headers: {
          "Content-Type": "application/json",
        },
      });

      if (response.status === 200) {
        //...your code on submit success
                console.log("submitted successfully")
      }
    } catch (error) {
            //...your code on submit unsuccessful
      console.log(error?.response?.data);
    }
  };
Enter fullscreen mode Exit fullscreen mode

References:

Top comments (0)