Tips for effectively invoking an API within a Next.js application

I've been exploring the most effective method for calling an external API within a Next.js application recently. Given my experience in developing MERN stack applications, I typically rely on axios for handling API requests and utilize it within a useEffect hook. Venturing into the world of Next.js, I encountered various concepts such as server components which led to some confusion. Despite this, I attempted the following approach which seems to function correctly, but I am left wondering: is this truly the recommended practice?

my-next-app>app>api>hello>route.ts

import axios from "axios";

export async function GET() {
  const response = await axios.get("http://localhost:5000");

  return Response.json(response.data);
}

my-next-app>hello>page.tsx

"use client";

import axios from "axios";
import * as React from "react";

export default function page() {
  const [msg, setMsg] = React.useState("");

  React.useEffect(() => {
    axios.get("api/hello").then((res) => {
      // { msg: "Hello World!" }
      setMsg(res.data.msg);
    });
  }, []);

  return <div>{msg}</div>;
}

Answer №1

For this scenario, the client has the option to directly call the API without the need for secret tokens and without mixing data with other server-side information. Essentially, the server's involvement in this process is minimal.

However, if authentication against the API requires a secret token known only to the server, the server route would be structured differently:

const secret = 'abcd1234'

export async function GET() {
  const response = await axios.get(`http://externalhost.com?secret=${secret}`);
  return Response.json(response.data);
}

If there is a need to filter out sensitive data from the API response that users should not have access to, additional steps must be taken:

const secret = 'abcd1234'

export async function GET() {
  const response = await axios.get(`http://externalhost.com?secret=${secret}`);
  const data = response.data.filter(item => !item.hasSensitiveData)
  return Response.json(data);
}

This adds complexity to the process, especially when dealing with sensitive information that could compromise security if exposed to users.

In reality, servers typically take ownership of external interfaces because they may possess unique data or for security reasons preventing clients from handling certain tasks.


Overall, the setup appears to be acceptable in this context.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Issue encountered when attempting to send FormData from Next.js API to Express.js backend resulting in Error 405: Bad Request

SOLVED / SEE MY OWN ANSWER FOR DETAILS Encountering a perplexing error that has left me stuck. I am currently facing an issue where I am trying to send an audio recording captured by the user in my Next.js Frontend to my Next.js API, which appears to be f ...

Is it possible to implement lazy loading for data in TypeScript classes?

Looking to optimize my Angular application's data structure when consuming a RESTful API. My goal is to only load necessary data from the server on demand. For instance, if I have a collection of Building objects each with a set of tenant IDs in an a ...

Restricting types does not appear to be effective when it comes to properties that are related

I am working with a specific type that looks like this: type Props = { type: 'foo'; value: string; } | { type: 'baz'; value: number; }; However, when using a switch statement with the type property in TypeScript, the program in ...

AngularJS 2 TypeScript structure

My application includes a user service for managing user operations and an interface for the user object. user.service.ts import {Injectable} from 'angular2/core'; export interface User { name: string; email?: string; picture?: string; } ...

Exploring Angular's Subcomponents

While working on my application, I encountered a dilemma. I currently pass data from the main component to the subcomponents after pulling it from the API with a single request. Should I continue with this approach or have each component make its own separ ...

Next-auth is in need of a username for the credentials provider

I am currently trying to learn how to implement next-auth in Next.js 13. I have set up a credentials login system with username and password. When I make an API request, I expect to receive a status code of 200 if the credentials are correct. The logic f ...

RxJs Subject: Acquiring the Sender

I have been working with Subjects and there is a .subscribe() in a specific class. Emitting values to this class from different other classes has resulted in the subscribe function being triggered multiple times, yet I am unsure of where these emits are co ...

Karma Unit test: Issue with accessing the 'length' property of an undefined value has been encountered

While running karma unit tests, I encountered a similar issue and here is what I found: One of my unit tests was writing data to a json file, resulting in the following error: ERROR in TypeError: Cannot read property 'length' of undefined a ...

Explore the functionality of a TypeScript-created Vue component by testing it with Vue-test-utils

In my attempt to validate props with various data types in a Vue component (built using TypeScript), I utilized the Vue-test-utils package. Despite implementing expect().tobe(), there remains an untested line: DropDownList.vue <template> <v-sel ...

typescript is reporting that the variable has not been defined

interface User { id: number; name?: string; nickname?: string; } interface Info { id: number; city?: string; } type SuperUser = User & Info; let su: SuperUser; su.id = 1; console.log(su); I experimented with intersection types ...

Creating static HTML files for non-static pages using Next.js SSR/ISR

While troubleshooting an issue with a specific page, I noticed that a static HTML file was created for a non-static page using Next.js. Is this expected? The page, which we will refer to as "page1," does not include the functions getStaticPaths() or getSta ...

Serve both .ts and .js files to the browser using RequireJs

In my ASP.NET Core Project, the following files are present: greet.ts export class WelcomMesssage { name: string; constructor(name: string) { this.name = name; } say(): void { console.log("Welcome " + this.name); } } GreetExample.ts import * as ...

Utilizing TypeScript 3.1: Easier Array Indexing with Enums in Strict Mode

Enabling TypeScript "strict" mode with "noImplicitAny" causes this code to fail compilation. I am looking for guidance on how to properly declare and use Arrays indexed by Enum values. namespace CommandLineParser { enum States { sNoWhere, sSwitchValu ...

The addition of an asynchronous call caused Array.map to start experiencing errors

I am working on a React component that iterates through an array of messages and renders JSX based on certain conditions: messages.map(async (msg) => { let previewImage: URL | undefined = undefined; if (msg.mediaId) { previewImage = await stora ...

What are the best practices for styling a component in Fluent UI when using React and TypeScript?

I'm attempting to set a background color for this specific div element: import * as React from 'react' import { Itest } from '../../../../../models' import { getPreviewStyles } from './preview.style.ts' type IPreviewP ...

Leveraging the power of Next.js version 13 in tandem with Elastic

I can't seem to figure out why I am getting an error when trying to read from an existing index using this API route and client-side page setup: import { Client } from "@elastic/elasticsearch"; import { NextResponse } from "next/server& ...

Encountered an error while trying to generate the Component class for the ColorlibStepIcon from Material UI in TypeScript

I am trying to convert the ColorlibStepIcon functional component into a class component for my Stepper. Unfortunately, I have not been successful and keep encountering errors. I have attempted some changes but it is still not working as expected. You can ...

Using Javascript to parse SOAP responses

Currently, I am working on a Meteor application that requires data consumption from both REST and SOAP APIs. The SOAP service is accessed using the soap package, which functions properly. However, I am facing challenges with the format of the returned data ...

Retrieve functions with varying signatures from another function with precise typing requirements

My code includes a dispatch function that takes a parameter and then returns a different function based on the parameter value. Here is a simplified version: type Choice = 'start' | 'end'; function dispatch(choice: Choice) { switch ...

Issue with value persisting after form reset

When looking at this snippet of code, I notice that even though all the values are being reset when the form is reset, the value of swt_culture_type remains unchanged. const { data: GetCultureTestHeadersDetails } = useQuery({ queryKey: ["headerDat ...