Creating Your First API Endpoint

Introduction: What Is An API Endpoint?

Welcome to your first lesson in backend development with Remix! In this course, you will learn how to build the backend part of a web application using Remix API routes.

Let’s start with a simple question: What is an API endpoint?
An API endpoint is a specific URL on your server that can receive requests and send back responses. Think of it as a door to your application’s data or features. For example, when you visit a website and see a list of products, your browser is often talking to an API endpoint behind the scenes to get that data.

In this lesson, you will create your very first API endpoint using Remix. This is a key skill for building modern web applications and will be the foundation for everything else you do in this course.

Why Remix for Backend Development?

Before we dive into more details, let’s take a moment to understand what Remix is and why we’re using it. Remix is a full-stack web framework that lets you build both frontend and backend logic in the same project. It’s built on top of React and Node.js, and it’s designed to handle routing, data loading, and server-side logic in a unified way.

Here’s what makes Remix a great choice for backend development:

  • Unified project structure: Frontend and backend code live in the same codebase.
  • File-based routing: Your file and folder structure directly defines your URLs.
  • API routes: You can create backend endpoints by adding files to app/routes.
  • Server-side execution: Loaders and actions run on the server.
  • Modern tooling: Remix uses Vite for fast builds and instant reloads.

In this course, we’ll focus on the backend side of Remix — specifically API routes, loaders, and actions — to learn how to handle requests and return structured JSON responses.

Installing and Running Remix

If you are working inside CodeSignal, Remix is already fully configured for you.
You don’t need to install or set up anything — you can start writing code right away.

If you want to work on your local machine, follow these steps.

Check Node.js installation

node -v
npm -v

Create a new Remix project

For local development, create a new project using the recommended starter:

npx create-react-router@latest

When prompted:

  • Choose TypeScript
  • Install dependencies
  • Accept the default configuration

This setup provides the full Remix experience, including file-based routing, loaders, and actions.

Run the development server

npm run dev

Your app will start at localhost:3000.

💡 Tip: Remix uses Vite, so changes you make to files are reflected almost instantly in the browser.

How the Remix App Is Structured

Let’s look at the most important parts of a Remix app:

app/
  routes/
    api.hello.ts
    _index.tsx
  entry.server.tsx
  entry.client.tsx
  root.tsx

Key concepts

  • app/routes/
    This folder defines your application’s routes — including API endpoints.

  • File-based routing
    Each file inside app/routes becomes a route.

  • Folders and dots create URL segments

    • Folders create nested paths
    • Dots (.) in filenames also create nested URL segments

Examples:

app/routes/api.hello.ts         → /api/hello
app/routes/users.list.tsx       → /users/list
app/routes/admin.users.tsx      → /admin/users

Route Modules, Loaders, and Actions

Each file inside app/routes is called a route module.
A route module can export server-side functions that handle requests. When a route module is intended to be an API endpoint, omit the default React component so Remix treats it as a resource route and returns the loader Response directly.

loader

  • Handles GET requests for a route and is responsible for reading data without modifying it.
  • It runs on the server every time the route is requested, whether the request comes from a browser navigation, a fetch call, or a page reload.
  • Loaders are commonly used to fetch data from databases, external APIs, or other backend services and then return that data to the route.
  • The data returned by a loader is made available to the route’s React component through Remix’s useLoaderData hook.

action

  • Handles data-changing requests, such as form submissions or API calls that create, update, or delete data.
  • This course focuses on GET requests with loaders; you’ll learn actions in a later course when we practice non-GET methods.

These functions are defined inside the route file itself, alongside (optional) React components.

Building Your First API Route

Now let’s create your first API endpoint.

Create a file called api.hello.ts inside the app/routes folder.

This route will respond to GET requests at:

/api/hello

API route implementation

import { json, type LoaderFunctionArgs } from "@remix-run/node";
import { useLoaderData } from "@remix-run/react";

export async function loader({ request }: LoaderFunctionArgs) {
  const timestamp = new Date().toISOString();

  const responseData = {
    message: "Hello, World!",
    timestamp,
    endpoint: "/api/hello",
    method: "GET",
    status: "success",
  };

  console.log(`GET request received at /api/hello at ${timestamp}`);

  return json(responseData);
}

export default function ApiHelloRoute() {
  const data = useLoaderData<typeof loader>();

  return (
    <main>
      <pre aria-label="/api/hello JSON response">
        {JSON.stringify(data, null, 2)}
      </pre>
    </main>
  );
}

What’s Happening in This Route?

The loader function

  • Runs when /api/hello is requested with GET
  • Builds a structured response object
  • Returns JSON using Remix’s json() helper

Using json() ensures:

  • Correct response headers
  • Proper serialization
  • Consistent behavior across environments

The default export component

Remix expects every route module to export a React component.
Even though this is an API-focused route, providing a minimal component prevents runtime warnings and allows the response to be viewed in the browser.

This component:

  • Reads the loader’s data using useLoaderData
  • Displays the JSON response in a readable format

Example Response

Visiting /api/hello returns:

{
  "message": "Hello, World!",
  "timestamp": "2024-06-01T12:34:56.789Z",
  "endpoint": "/api/hello",
  "method": "GET",
  "status": "success"
}

Why Include Extra Metadata?

Including structured fields like these is a common backend practice:

  • timestamp helps with debugging and logging
  • endpoint clarifies which route handled the request
  • method shows how the endpoint was accessed
  • status provides a simple success indicator

This structure makes APIs easier to debug, test, and extend.

Summary and What’s Next

In this lesson, you learned how to:

  • Understand what an API endpoint is
  • Set up and run a Remix project
  • Use file-based routing to define API routes
  • Write a loader to handle GET requests
  • Return structured JSON responses from the server

Next, you’ll practice creating and modifying API routes yourself, building confidence with Remix’s backend model before moving on to more advanced topics.

Have fun — you’re officially building backends now 🚀

Sign up

Join the 1M+ learners on CodeSignal

Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal