DEV Community

Oliver Kem
Oliver Kem

Posted on

tRPC APIs - Part 1

Hello Devs.

When it comes to APIs, the first thing that comes to your mind is RESTful and GraphQL APIs. While these two powers the modern web communication, there's this new talk in town, tRPC (typesafe Remote Procedure Call). This is a framework for writing APIs meaning it offers all advantages of REST and GraphQL APIs are more such as:

  • Type safely for both client and server.
  • Abstraction on schema
  • Secure Connection from client to server

and more....
What do you mean 🤔🤔🤔🤔🤔🤔🤔? Check this out. Let's start with how APIs changed the world

Rest APIs

When rest APIs came, they provided a means of fetching and push data from the server to client fast, lightweight and easier because data was sent and retrieved in JSON format. But as applications grew, there as need of a predefined way or schema where people could know exactly what they are fetching and they could filter what they could fetch from the server because Rest APIs returns alot of information (over fetching) or little information (under fetching) which in most cases is unnecessary

GraphQL

In 2012, Facebook started developing GraphQL to address the major concerns of Rest APIs and solve on scalability of their applications, at first it was developed to be used internally until 2015 where they released it to the Public (open source). This got the community so much involved in the project that they started contributing to the GraphQL project and developed libraries like ApolloGraphQL, GraphQL Yoga, Express GraphQL e.t.c. And while GraphQL solved alot of problems, the whole idea of defining a schema for requests was somehow hectic. When your application starts to scale you'll need to create each schema for each request and resource you want to fetch.

tRPC

tRPC mean *TypeSafe - Remote Procedure Call *. RPC mean *** remote procedure call ** this basically means allowing a machine or device from one device to call a function from another PC or machine. When you at typesafe, this maintains type safety between the (one machine)client and (other machine)server such that you can develop your application safely and easily.

Let's begin. We will start by creating our backend. So, go to your terminal and run the following.

$ mkdir trpc
$ cd trpc
$ mkdir trpc-backend
$ cd trpc-backend

$pnpm init -y
$ code .

Enter fullscreen mode Exit fullscreen mode

Now let us install a couple of dependencies, express, @trpc/server, zod cors. I will also be using typescript, so let us install some types library @types/node, @types/express, nodemon, typescript

$ pnpm add express zod cors @trpc/server
$ pnpm add -D @types/node @types/express nodemon typescript
Enter fullscreen mode Exit fullscreen mode

Project setup

Now, from this image, we will initialize our application, set your package.json to look exactly like mine.
Now make a root directory called src. Then inside, create two directories data and trpc. Inside the data, create an index.ts file, then paste the following.

export const books=[
    {
        id:1,
        title:"The Lord of the Rings",
        author: "J.R.R. Tolkien",
        price: 20,
        img: "https://images-na.ssl-images-amazon.com/images/I/51UoqRAxwEL._SX331_BO1,204,203,200_.jpg",
        description: "The Lord of the Rings is an epic high fantasy novel by the English author and scholar J. R. R. Tolkien. Set in Middle-earth, the world at some distant time in the past, the story began as a sequel to Tolkien's 1937 children's book The Hobbit, but eventually developed into a much larger work. Written in stages between 1937 and 1949, The Lord of the Rings is one of the best-selling books ever written, with over 150 million copies sold."
    },
    {
        id:2,
        title:"The Hobbit",
        author: "J.R.R. Tolkien",
        price: 15,
        img: "https://images-na.ssl-images-amazon.com/images/I/51o5n%2B1Q%2BtL._SX331_BO1,204,203,200_.jpg",
        description: "The Hobbit, or There and Back Again is a children's fantasy novel by English author J. R. R. Tolkien. It was published on 21 September 1937 to wide critical acclaim, being nominated for the Carnegie Medal and awarded a prize from the New York Herald Tribune for best juvenile fiction. The book remains popular and is recognized as a classic in children's literature."
    },
    {
        id:3,
        title:"The Silmarillion",
        price: 25,
        author: "T.B Tolkien",
        img: "https://images-na.ssl-images-amazon.com/images/I/51Q5ZQ%2BZ1TL._SX331_BO1,204,203,200_.jpg",
        description: "The Silmarillion is a collection of mythopoeic works by English writer J. R. R. Tolkien, edited and published posthumously by his son, Christopher Tolkien, in 1977, with assistance from Guy Gavriel Kay. The Silmarillion, along with J. R. R. Tolkien's other works, forms an extensive, though incomplete, narrative that describes the universe of Eä in which are found the lands of Valinor, Beleriand, Númenor, and Middle-earth, within which The Hobbit and The Lord of the Rings take place."
    },
    {
        id:4,
        title:"The Children of Húrin",
        price: 30,
        author: "J.R.R. Tolkien",
        img: "https://images-na.ssl-images-amazon.com/images/I/51Q5ZQ%2BZ1TL._SX331_BO1,204,203,200_.jpg",
        description: "The Children of Húrin is an epic fantasy novel which forms the completion of a tale by J. R. R. Tolkien. He wrote the original version of the story in the late 1910s, revised it several times later, but did not complete it before his death in 1973. His son, Christopher Tolkien, edited the manuscripts to form a consistent narrative, and published it in 2007 as an independent work."

    },
];
Enter fullscreen mode Exit fullscreen mode

We will be using this as our dummy database data. Feel free to add some database functionality to retrieve and add data.
Now, inside the trpc folder we created, add a file called trpc.ts, then paste the following lines of code.

import { initTRPC } from "@trpc/server";
import {z} from 'zod';
import { books } from "../data/index.ts";
const t  = initTRPC.create()
const publicProcedure = t.procedure;

export const appRouter = t.router({
    greeting: publicProcedure
        .query(()=>{
            return "Hello World"
        }),
    getBooks: publicProcedure
        .query(()=>{
            return books;
        }),
    fetchABook: publicProcedure
        .input(z.object({
            id: z.number(),
        }))
        .query(({input})=>{
            console.log(input);
            const book =  books.find((book)=>book.id === input.id)
            console.log(book);
            return book;
        }),
    addABook: publicProcedure
        .input(z.object({
            title: z.string(),
            id: z.number(),
            author: z.string(),
            description: z.string(),
            price: z.number(),
            img: z.string(),
        }))
        .mutation(({input})=>{
            books.push({
                title: input.title,
                id: input.id,
                img: input.img,
                description: input.description,
                price: input.price,
                author: input.author,
            });
            return input;
        }),

})
export type AppRouter = typeof appRouter;
Enter fullscreen mode Exit fullscreen mode

From above, we have initialized trpc with initTRPC, we have then used zod as an input validator, we will use this to validate our inputs before executing a query.
Now, let us test our application.
Go to your terminal and run the following.
Now, we need to have a wrapper that will be our web server to hosting our API. Inside the src folder, create a file called index.ts add the following

import { appRouter, } from "./trpc/trpc.ts";
import express from 'express';
import * as trpExpress from '@trpc/server/adapters/express';
import cors from 'cors';
const app = express();
app.use(cors());
app.use(express.json());
app.use('/trpc',
    trpExpress.createExpressMiddleware({
        router: appRouter,
        createContext: ({req,res}) => {
            const token = req.headers.authorization;

            return {
                // this is where you would put your auth, db, etc...
            }
        },

    })
);
app.get('/',(req,res)=>{
    return res.json({message:"Hello World"});
});
app.listen(3000,()=>{
    console.log("Server started on port 3000");
});

Enter fullscreen mode Exit fullscreen mode

From above, we have just imported the server instance we created. Now we use the express adapters, we use express for our backend instance, you can use other wrappers like NextJS, if you are building a nextJS application. We use cors to help query to our backend instance. Now with this, let us start.

$ pnpm dev
Enter fullscreen mode Exit fullscreen mode

Now, you can use postman or your browser to test the endpoints.
Go to https//localhost:3000/trpc/greeting on your browser. You should get the following response

Request Output
IF you get this, it means your backend server is successfully running. Now with this, you are good to go. I will be continuing with part two.

Top comments (0)