How to Create API Endpoints in Bun ๐ŸŒŸ

How to Create API Endpoints in Bun ๐ŸŒŸ

ยท

5 min read

Creating APIs is an integral part of modern web development. Whether you're building a simple backend for a single-page app or designing a robust service for a large-scale application, you need tools that make the process efficient. Enter Bun ๐ŸŽ‰, a modern JavaScript runtime that simplifies the process with its built-in HTTP server. In this guide, weโ€™ll explore how to create API endpoints in Bun and why itโ€™s an excellent choice for developers.


What is Bun? ๐Ÿค”

Bun is a high-performance JavaScript runtime designed to be blazing fast โšก๏ธ. It combines a JavaScript runtime, a bundler, and a package manager into one cohesive tool. One of Bunโ€™s standout features is its native HTTP server, which eliminates the need for external libraries like Express to create simple APIs. ๐Ÿ’จ


Getting Started ๐Ÿš€

To follow along, make sure you have Bun installed. If you havenโ€™t installed it yet, you can do so by following the instructions on Bunโ€™s official website. ๐Ÿ› ๏ธ

Once installed, weโ€™re ready to create a basic API endpoint in Bun. Letโ€™s dive in! ๐ŸŒŠ


๐Ÿš€ How to Create Your First API Endpoint in Bun

In this section, weโ€™ll guide you step-by-step on how to create a simple API endpoint in Bun, with an easy way to change the port number. Bun makes it simple to build fast APIs, and weโ€™ll show you how to set up a basic server that you can customize.

โš™๏ธ Setting Up the Server with a Custom Port

Letโ€™s start by creating a simple API server in Bun. The port number can be set using a command when you run the server, making it flexible depending on your needs:

import { serve } from "bun";

// Get the port from the command line, default to 3000 if not provided
const port = process.argv[2] || 3000;

serve({
  port: Number(port), // Convert the port to a number
  fetch(req) {
    const url = new URL(req.url);

    // Create a simple GET endpoint
    if (url.pathname === "/api/hello" && req.method === "GET") {
      return new Response(JSON.stringify({ message: "Hello, Bun!" }), {
        status: 200,
        headers: { "Content-Type": "application/json" },
      });
    }

    // Return 404 for other routes
    return new Response("Not Found", { status: 404 });
  },
});

๐Ÿ” How It Works

  • Port Customization: We use process.argv to get the port number from the command you use to start the server. If you donโ€™t specify a port, it will default to 3000. This gives you flexibility when running the server. ๐ŸŒ

  • The serve Function: This is the main function that tells Bun to create an HTTP server. The server listens for requests and handles them using the fetch function. ๐ŸŒ

  • Request Handling: The fetch function checks the URL to see if it matches /api/hello with a GET request. If it does, it sends back a simple greeting. If not, it returns a 404 Not Found error. ๐Ÿšซ

๐Ÿ–ฅ๏ธ Running the Server

To start the server, save the file (for example, server.js) and run this command in your terminal:

run server.js 5000

This will start the server on port 5000. To test it, visit http://localhost:5000/api/hello in your browser. You should see the following message:

{
  "message": "Hello, Bun!"
}

If you donโ€™t specify a port, the server will default to port 3000. ๐ŸŽ‰


Adding Dynamic and Advanced Routing ๐Ÿ› ๏ธ

To build more versatile APIs, letโ€™s implement dynamic routing and support for different HTTP methods:

import { serve } from "bun";

serve({
  port: 3000,
  fetch(req) {
    const url = new URL(req.url);

    // Handle POST requests with a JSON body
    if (url.pathname === "/api/greet" && req.method === "POST") {
      return req.json().then((body) => {
        const name = body.name || "Guest";
        return new Response(
          JSON.stringify({ message: `Hello, ${name}!` }),
          {
            status: 200,
            headers: { "Content-Type": "application/json" },
          }
        );
      });
    }

    // Dynamic route example: /api/user/:id
    if (url.pathname.startsWith("/api/user/") && req.method === "GET") {
      const userId = url.pathname.split("/").pop();
      return new Response(
        JSON.stringify({ userId, message: `User ID is ${userId}` }),
        {
          status: 200,
          headers: { "Content-Type": "application/json" },
        }
      );
    }

    return new Response("Not Found", { status: 404 });
  },
});

Features in This Example ๐ŸŒŸ

  1. Dynamic Parameters: Extract dynamic segments like userId from the URL using url.pathname. ๐Ÿ”€

  2. JSON Parsing: Use Bunโ€™s req.json() to parse incoming JSON payloads in POST requests. ๐Ÿ“ฆ

  3. Error Handling: Return a 404 response for undefined routes. ๐Ÿšซ

Testing the Endpoints ๐Ÿ’ป

GET Request to /api/user/:id

Run this command:

curl http://localhost:3000/api/user/123

Response:

{
  "userId": "123",
  "message": "User ID is 123"
}

POST Request to /api/greet

Send a POST request with JSON data:

curl -X POST http://localhost:3000/api/greet \
     -H "Content-Type: application/json" \
     -d '{"name": "Alice"}'

Response:

{
  "message": "Hello, Alice!"
}

Why Use Bun for APIs? ๐Ÿ†

  1. Blazing Performance: Bun is built for speed, leveraging Zig and optimized runtime design to outpace traditional JavaScript runtimes. โšก๏ธ

  2. Simplicity: Its built-in HTTP server removes the need for additional libraries like Express, simplifying your development process. ๐ŸŒ

  3. All-in-One Tool: With a runtime, bundler, and package manager rolled into one, Bun streamlines your workflow. ๐Ÿ”„


Conclusion ๐ŸŽฏ

Bun makes creating lightweight, high-performance APIs a breeze. Whether youโ€™re developing a simple app or a production-ready system, Bunโ€™s features like native routing and JSON parsing make it a top choice for modern web development. ๐ŸŒˆ

Try out Bun today and see how it can supercharge your API development! ๐Ÿš€

ย