Integrations

Hono Integration

URPC provides seamless Hono integration. This guide shows you how to integrate URPC with Hono for building fast and lightweight web APIs.

Install Dependencies

First, install the required dependency packages:

npm install @unilab/urpc-hono @unilab/urpc @unilab/urpc-core @unilab/urpc-adapters hono @hono/node-server

Project Structure

hono-basic/
├── entities/
│   ├── user.ts               # User entity
│   └── post.ts               # Post entity
├── server.ts                 # Server setup
├── client.ts                 # Client usage
├── package.json
└── tsconfig.json

Entity Definition

Define your entities using URPC decorators:

User Entity:

import { Fields } from "@unilab/urpc-core";
import { PostEntity } from "./post";

export class UserEntity {
  @Fields.string()
  id = "";

  @Fields.string()
  name = "";

  @Fields.string()
  email = "";

  @Fields.string()
  avatar = "";

  @Fields.array(() => PostEntity, {
    optional: true,
  })
  posts?: PostEntity[];
}

Post Entity:

import { Fields } from "@unilab/urpc-core";
import type { UserEntity } from "./user";

export class PostEntity {
  @Fields.string()
  id = "";

  @Fields.string()
  title = "";

  @Fields.string()
  content = "";

  @Fields.string()
  userId = "";

  @Fields.record(() => require("./user").UserEntity, {
    optional: true,
  })
  user?: UserEntity;
}

Server Setup

Configure your Hono server with URPC using MockAdapter for development:

import { URPC } from "@unilab/urpc-hono";
import { UserEntity } from "./entities/user";
import { PostEntity } from "./entities/post";
import { Plugin } from "@unilab/urpc-core";
import { MockAdapter } from "@unilab/urpc-adapters";

const MyPlugin: Plugin = {
  entities: [UserEntity, PostEntity],
};

const app = URPC.init({
  plugins: [MyPlugin],
  entityConfigs: {
    user: {
      defaultSource: "mock",
    },
    post: {
      defaultSource: "mock",
    },
  },
  globalAdapters: [MockAdapter],
});

// Initialize sample data
await URPC.repo<UserEntity>({
  entity: "UserEntity",
  source: "mock",
}).create({
  data: {
    id: "1",
    name: "John Doe",
    email: "[email protected]",
    avatar: "https://example.com/avatar.png",
  },
});

await URPC.repo<PostEntity>({
  entity: "PostEntity",
  source: "mock",
}).create({
  data: {
    id: "1",
    title: "Post 1",
    content: "Content 1",
    userId: "1",
  },
});

export default {
  port: 3000,
  timeout: 30000,
  fetch: app.fetch,
};

Client Usage

Use the URPC client to interact with your API with advanced relationship queries:

import { UserEntity } from "./entities/user";
import { PostEntity } from "./entities/post";
import { repo, URPC, joinRepo } from "@unilab/urpc";

URPC.init({
  baseUrl: "http://localhost:3000",
  timeout: 10000,
});

// Fetch user with posts using include
const fetchUser = async () => {
  const data = await repo<UserEntity>({
    entity: "user",
  }).findMany({
    where: {
      id: "1",
    },
    include: {
      posts: (userList) => {
        const ids = userList.map((user) => user.id);
        
        // If you don't set the where parameter, you must use joinRepo, but in other cases you can use repo directly.
        return joinRepo<PostEntity, UserEntity>({
          entity: "post",
          localField: "id",
          foreignField: "userId",
        }).findMany({
          where: {
            userId: {
              $in: ids,
            },
          },
        });
      },
    },
  });
  console.log("User with posts:", JSON.stringify(data, null, 2));
};

// Fetch post with user relationship
const fetchPost = async () => {
  const data = await repo<PostEntity>({
    entity: "post",
  }).findOne({
    where: {
      id: "1",
    },
    include: {
      user: (post) => {
        const userId = post.userId;
        return repo<UserEntity>({
          entity: "user",
        }).findOne({
          where: {
            id: userId,
          },
        });
      },
    },
  });
  console.log("Post with user:", JSON.stringify(data, null, 2));
};

fetchUser();
fetchPost();

Running the Application

Start your Hono server:

bun run dev
# or
bun run server.ts

Run the client to test the API:

bun run client
# or  
bun run client.ts

Your URPC-powered Hono API will be available at http://localhost:3000.

Key Features

Entity Configuration

URPC allows you to configure default sources for entities:

entityConfigs: {
  user: {
    defaultSource: "mock",  // Default adapter for user operations
  },
  post: {
    defaultSource: "mock",  // Default adapter for post operations  
  },
}

Global Adapters

Use global adapters like MockAdapter for development:

globalAdapters: [MockAdapter]

Relationship Queries

URPC supports complex relationship queries:

  • Include: Load related data with the main query
  • JoinRepo: Handle foreign key relationships efficiently
  • Nested relationships: Support for deep relationship loading

MockAdapter Benefits

The MockAdapter provides:

  • In-memory data storage for development
  • No database setup required
  • Fast prototyping and testing
  • Automatic relationship handling

This makes it perfect for getting started quickly with URPC and Hono integration.