Skip to content

Pyxlab/adonis-trpc

Repository files navigation



A tRPC provider for AdonisJs

@pyxlab/adonis-trpc provides an easy way to start using tRPC.


npm-image license-image typescript-image

Installation

Let's start by installing the package in our project.

Yarn:

yarn add @pyxlab/adonis-trpc

NPM:

npm install @pyxlab/adonis-trpc

Usage

Configuration

In command line, run the following command to generate the configuration file.

node ace configure @pyxlab/adonis-trpc

Start

Procedures should be placed inside app/Routes folder.

All routes are defined inside app/Routes/index.ts file. The routes are grouped by the folder name. For example, the app/Routes/Posts folder contains all routes related to posts.

The app/Routes/index.ts file is the entry point for all routes. It is used to import all routes and export them as a single object.

import router from '@ioc:Pyxlab/Adonis/Trpc/Router'
import { postsRouter } from 'App/Routes/Post'

const appRouter = router({
    posts: postsRouter,
})

export default appRouter

export type AppRouter = typeof appRouter

The app/Routes/Post/index.ts file is the entry point for all posts routes. It is used to import all routes and export them as a single object.

import router from '@ioc:Pyxlab/Adonis/Trpc/Router'
import { createPost } from 'App/Routes/Posts/createPost'
import { getPosts } from 'App/Routes/Posts/getPosts'

export const postRouter = router({
    createPost,
    getPosts,
})

The app/Routes/Posts/createPost.ts file is the route handler for the createPost route.

import procedure from '@ioc:Pyxlab/Adonis/Trpc/Procedure'
import { z } from 'zod'

const input = z.object({
    title: z.string(),
    body: z.string(),
})

export const createPost = procedure
    .protected
    .input(input)
    .mutation(async ({ ctx: { auth }, input }) => {
        const user = auth.user!

        const post = await user.related('posts').create(input)

        return post.serialize()
    })

In the above example, the createPost route is defined. The protected property is used to define a protected route. The input method is used to define the input schema.

The ctx object is the AdonisJS context object. The auth property is the AdonisJS authentication object. The auth.user property is the authenticated user.

The mutation method is used to define the route handler. The mutation method is used to define a route that modifies the resource. The query method is used to define a route that does not modify the resource.

The createPost route handler creates a new post for the authenticated user. The post.serialize() method is used to serialize the post model.

The app/Routes/Posts/getPosts.ts file is the route handler for the getPosts route.

import procedure from '@ioc:Pyxlab/Adonis/Trpc/Procedure'

export const getPosts = procedure
    .protected
    .query(async ({ ctx: { auth } }) => {
        const user = auth.user!

        const posts = await user.related('posts').findMany()

        return posts.serialize()
    })

In the above example, the getPosts route is defined. The protected property is used to define a protected route.

The method serializes the posts models and returns them. but the serialize method is inherited from the BaseModel class. So that infer the type of the model without BaselModel, we need to override the serialize method.

import { BaseModel, column, InferTypeModel } from '@ioc:Adonis/Lucid/Orm'

export default class Post extends BaseModel {
    @column({ isPrimary: true })
    public id: number

    @column()
    public title: string

    @column()
    public body: string

    @column()
    public userId: number

    public override serialize(cherryPick?: CherryPick) {
        return super.serialize(cherryPick) as InferTypeModel<Role>
    }
}

The InferTypeModel type is used to infer the type of the model. The serialize method is overridden to return the type of the model.

Procedure Generator

To generate a procedure, run the following command. The above command will create a procedure file in the app/Routes directory, with the template name provided and the .ts extension. It will also create a folder with the template name if it does not already exist.

node ace make:procedure <model-name> <?procedure-name>

The model-name is the name of the model. The procedure-name is the name of the procedure. If the procedure-name is not provided, only the folder and index.ts will be created.

Options

  --exact or -e: Creates the procedure with the exact name provided, without adding the Procedure suffix.
  --model or -m: Creates a model with the name of the supplied model.
  --table or -t: Creates a migration with the name of the provided model.
  --resource or -r: Adds resource methods (getById, create, list, update, delete) to the procedure file created.

Examples

node ace make:procedure Auth createSession --exact

The above command will create a procedure file in the app/Routes/Auth directory, with the createSession name and the .ts extension.

node ace make:procedure CostCenter --model --table --resource

The above command will create a procedure file in the app/Routes/CostCenter directory, with the index name and the .ts extension. It will create a model and a migration with the name of the provided model. and it will add resource methods (getCostCenterById, createCostCenter, listCostCenter, updateCostCenter, deleteCostCenter) to the procedure file created.

Contributing

Thank you for being interested in making this package better. We encourage everyone to help improve this project with new features, bug fixes, or performance improvements. Please take a little bit of your time to read our guide to make this process faster and easier.

Contribution Guidelines

To understand how to submit an issue, commit and create pull requests, check our Contribution Guidelines.

Code of Conduct

We expect you to follow our Code of Conduct. You can read it to understand what kind of behavior will and will not be tolerated.

License

MIT License © Pyxlab

Built with ❤︎ by Walaff Fernandes