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

Entity Definition

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[];
}
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

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

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

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

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

Client Usage

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

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();