DEV Community

Oliver Kem
Oliver Kem

Posted on

tRPC APIs - Part 2

Hello everyone!

welcome back, in our first session we had implemented our backend server of the tRPC apis where we built a simple server that fetches books from some datasource and returns that in json format. We also tested our aplication and it worked fine. In this section, we are going to build our frontend that interacts with our backend server, fetches data and displays it in our app. To do this, I will be building a simple React application using vite.

Prerequisites

  1. Part 1 of our session. Feel free to build your own
  2. Typescript
  3. React knowledge

Let us begin.

From our introduction, we mentioned that tRPC implements typesafe Remote Procedural Call and this basically means it allows a machine from one side to call another procedure or function from another machine. The typesafe bit means it leverages typescript for typesafety. This helps in code building and productivity boost during application development. Let us start developing our application
We had created a folder where we put two folders, trpc-backend and trpc-frontend. For now, navigate to the frontend folder and run the following command.

$ pnpm vite@latest
Enter fullscreen mode Exit fullscreen mode

Follow the prompt, I will also be using typescript. You should be getting something like this in the folder. However, feel free to develop it how you like.

Landing
Now let us continue with development, I will be using TailwindCSS for some styling and React Query for our state management. So let us initialize our application with tailwind.

$ pnpm add -D tailwindcss  postcss autoprefixer
$ npx tailwindcss init -p
$ pnpm add react-query 
$ pnpm add @trpc/client
Enter fullscreen mode Exit fullscreen mode

With this, let us to our index.css file, comment all the code add the following.

@tailwind base;
@tailwind components;
@tailwind utilities;
Enter fullscreen mode Exit fullscreen mode

Replace the code in the

`tailwind.config.js with this



/** @type {import('tailwindcss').Config} */
export default {
  content: [
    "./index.html",
    "./src/**/*.{js,jsx,ts,tsx}",
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}



Enter fullscreen mode Exit fullscreen mode

Now our application can use TailwindCSS.
In our

main.tsx

file, we need to wrap with react-query to make our state available for every component, to do so, paste the following



import App from './App.tsx'
import './index.css'
import { QueryClient, QueryClientProvider, } from 'react-query';
const queryClient = new QueryClient();

ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
  <React.StrictMode>
    <QueryClientProvider client={queryClient}>
    <App />
</QueryClientProvider>
  </React.StrictMode>,
)



Enter fullscreen mode Exit fullscreen mode

Now react-query will be available for our application.
Now let us go to our App.tsx file and add the following.

Here is where we will handle the state logic and the fetching logic. tRPC changed alot from version 9. So the documentation for integrating with react also changed.



import { AppRouter } from '../../trpc-backend/src/trpc/trpc';
import { createTRPCProxyClient, httpBatchLink} from '@trpc/client'
function App(){
    const trpcClient= createTRPCProxyClient<AppRouter>({
        links:[
            httpBatchLink({
                url: 'http://localhost:3000/trpc',
            }),
        ]
    });
}


Enter fullscreen mode Exit fullscreen mode

Let us go through this, here we imported the

AppRouter

type we had exported from our backend server, then we import the httpBatchLink and createTRPCProxyClient from the client library. We then set the link to the backend server and that is it. Now are ready to interact with our server data.
Next we import the functions that help up query



import {  useMutation, useQuery, useQueryClient } from 'react-query';
import { AppRouter } from '../../trpc-backend/src/trpc/trpc';
import { createTRPCProxyClient, httpBatchLink} from '@trpc/client'
type Book={
    id: number,
    title: string,
    img: string,
    description: string,
    price: number
    author: string
}
function App(){
    const {data,isLoading, isError,} = useQuery({
        queryKey: ['books'],
        queryFn: async () => await trpcClient.getBooks.query(),

    })
    const trpcClient= createTRPCProxyClient<AppRouter>({
        links:[
            httpBatchLink({
                url: 'http://localhost:3000/trpc',
            }),
        ]
    });
   if(isLoading) return <div>Loading...</div>
   if(isError) return <div>Error</div>
   return (
        <div>
            <h1 className="text-3xl font-bold">React tRPC and react query</h1>

            <div className='grid grid-cols-2 gap-1 md:grid md:grid-cols-3 md:gap-2'
            >
                {
                    data?.map((item: Book)=>{
                        return (
                            <div key={item.id} className='border-2 border-gray-200 rounded-md p-2 hover:bg-sky-500 transition ease-in-out delay-150'>
                                <img src={item.img} alt={item.title} className='w-32 h-32'/>
                                <h2 className='text-xl font-bold'>{item.title}</h2>
                                <p className='text-sm'>{item.description.slice(0,50)}...</p>
                                <p className='text-sm font-bold'>${item.price}</p>
                            </div>

                        )
                    })
                }
            </div>          
        </div>
    )
}


Enter fullscreen mode Exit fullscreen mode

With this code, we have just

Top comments (0)