The Nile-JS SDK includes generated routes for all its operations. These routes are used by the SDK methods to proxy requests to nile-auth, as well as directly from the React hooks and components in @niledatabase/react.

Generating routes

Route generation depends on the framework you are using.

Next.js example

// app/api/[...nile]/nile.ts
import { Nile } from "@niledatabase/server";

export const nile = await Nile({
  secureCookies: process.env.VERCEL === "1",
  debug: true,
});

export const { handlers } = nile.api;

Remix example

// app/nile.ts
import { Nile } from "@niledatabase/server";

export const nile = await Nile();
export const { handlers } = nile.api;

## Using routes

You typically don't need to use the routes directly. 
The SDK methods and react/web components use the routes under the hood to communicate with nile-auth.

The generated routes are available via `nile.api.paths`. For reference, here are the paths for the default routes:

```ts
export const appRoutes = (prefix = '/api'): Routes => ({
  SIGNIN: `${prefix}/auth/signin`,
  PROVIDERS: `${prefix}/auth/providers`,
  SESSION: `${prefix}/auth/session`,
  CSRF: `${prefix}/auth/csrf`,
  CALLBACK: `${prefix}/auth/callback`, // this path has a route per enabled provider (e.g. google, github, etc.)
  SIGNOUT: `${prefix}/auth/signout`,
  ERROR: `${prefix}/auth/error`,
  VERIFY_REQUEST: `${prefix}/auth/verify-request`,
  PASSWORD_RESET: `${prefix}/auth/reset-password`,
  ME: `${prefix}/me`,
  USERS: `${prefix}/users`,
  TENANTS: `${prefix}/tenants`,
  TENANT: `${prefix}/tenants/{tenantId}`,
  TENANT_USER: `${prefix}/tenants/{tenantId}/users/{userId}`,
  TENANT_USERS: `${prefix}/tenants/{tenantId}/users`,
  SIGNUP: `${prefix}/signup`,
  LOG: `${prefix}/_log`,
});

Overriding routes

Sometimes you might want to intercept or override the routes used by the SDK in order to inject your own logic. For example, adding your own logging or metrics, adding debugging information, or perhaps injecting your own cookies during login.

There are three ways to override routes:

  1. Route wrappers: Wrap the route in your own logic. This can be done in the routes file, and is useful for minor modifications or debugging.
  2. Route overrides: Override the route for a specific operation.

Route wrappers

In the examples below, we’ll use route wrappers to log the headers before every request and the body if it’s a POST request. We’ll also log the status code of the response.

// app/api/[...nile]/route.ts
import { handlers } from "./nile";

// Middleware function to log request and response details
const logRequestAndResponseDetails = (handler) => async (req, res) => {
  // Log the request method and URL
  console.log(`Request Method: ${req.method}, Request URL: ${req.url}`);

  // Log the request headers
  console.log('Request Headers:', req.headers);

  // Clone the request to safely read the body
  const clonedReq = req.clone();

  // Log the request body if it's a POST or PUT request
  if (req.method === 'POST') {
    const body = await clonedReq.text();
    console.log('Request Body:', body);
  }
  // Call the original handler and return its result
  const result = await handler(req, res);

  // Log the response status after the handler has executed
  console.log('Result Status:', result.status);

  return result;
};

// Wrap each handler with the logging middleware
export const POST = logRequestAndResponseDetails(handlers.POST);
export const GET = logRequestAndResponseDetails(handlers.GET);
export const DELETE = logRequestAndResponseDetails(handlers.DELETE);
export const PUT = logRequestAndResponseDetails(handlers.PUT);

Route overrides

In the examples below, we’ll add a new route that will override the default route for \auth\google\callback with custom logic.

// app/api/auth/google/callback/route.ts
import { NextRequest } from "next/server";
import { nile, handlers } from "../../../[...nile]/nile";
import { registerTenants } from "@/lib/TenantRegistration";

export async function GET(req: NextRequest) {
  const postHandled = await handlers.GET(req); // call the original route

  if (postHandled) {
    const setCookie = postHandled.headers.getSetCookie();
    const hasSession = setCookie.filter((c) =>
      c.includes("nile.session-token")
    );
    if (hasSession) { // if login was successful, register the tenants
      nile.api.headers = new Headers({ cookie: hasSession.toString() });
      const me = await nile.api.users.me();
      if ("id" in me) {
        // custom logic is here
        await registerTenants(me.id);
      }
    }
  }
  // return the original response from the route
  return postHandled;
}

Was this page helpful?