|
1 | 1 | # 05 API Routes |
| 2 | + |
| 3 | +In this example, we will migrate our previous API server to use TanStack Start API Routes. |
| 4 | + |
| 5 | +# Steps to build it |
| 6 | + |
| 7 | +`npm install` to install previous sample packages: |
| 8 | + |
| 9 | +```bash |
| 10 | +npm install |
| 11 | +``` |
| 12 | + |
| 13 | +TanStack Start provides a way to create [API routes](https://tanstack.com/start/latest/docs/framework/react/guide/server-routes) that can be used in your application without needing a separate backend server. This is particularly useful for small to medium-sized applications or when you want to keep everything within a single codebase. |
| 14 | + |
| 15 | +First, let's move the API logic from our previous server to the `src` folder. |
| 16 | + |
| 17 | +- Copy the contents of `./api-server/src/mock-data.ts` to `./src/db/mock-data.ts`. |
| 18 | +- Add the barrel file `./src/db/index.ts` with the content `export * from './mock-data';` |
| 19 | +- Copy cars images from `./api-server/public` to `./public`. |
| 20 | +- Remove the `./api-server` folder. |
| 21 | + |
| 22 | +Update the `package.json`: |
| 23 | + |
| 24 | +_./package.json_ |
| 25 | + |
| 26 | +```diff |
| 27 | +... |
| 28 | + "scripts": { |
| 29 | +- "start": "run-p -l start:dev start:api-server", |
| 30 | ++ "start": "vite", |
| 31 | +- "start:dev": "vite", |
| 32 | +- "start:api-server": "cd api-server && npm run mock-server", |
| 33 | +- "postinstall": "cd ./api-server && npm install" |
| 34 | + }, |
| 35 | +... |
| 36 | +``` |
| 37 | + |
| 38 | +Update the environment variables: |
| 39 | + |
| 40 | +_./.env.local_ |
| 41 | + |
| 42 | +```diff |
| 43 | +- BASE_API_URL=http://localhost:3001/api |
| 44 | ++ BASE_API_URL=http://localhost:5173/api |
| 45 | +- PUBLIC_BASE_PICTURES_URL=http://localhost:3001 |
| 46 | ++ PUBLIC_BASE_PICTURES_URL=http://localhost:5173 |
| 47 | + |
| 48 | +``` |
| 49 | + |
| 50 | +Run the development server: |
| 51 | + |
| 52 | +```bash |
| 53 | +npm start |
| 54 | +``` |
| 55 | + |
| 56 | +And let's to update the API requests. You can create an API route by defining [the `server` prop](https://tanstack.com/start/latest/docs/framework/react/guide/server-routes#server-routes-and-app-routes) on a page or layout component or by creating a dedicated file in another location, for example, in a `routes/api` folder. |
| 57 | + |
| 58 | +_./src/routes/api/cars/index.ts_ |
| 59 | + |
| 60 | +```ts |
| 61 | +import { cars } from '#db'; |
| 62 | +import { createFileRoute } from '@tanstack/react-router'; |
| 63 | +import { json } from '@tanstack/react-start'; |
| 64 | + |
| 65 | +export const Route = createFileRoute('/api/cars')({ |
| 66 | + server: { |
| 67 | + handlers: { |
| 68 | + GET: async () => { |
| 69 | + return json(cars); |
| 70 | + }, |
| 71 | + }, |
| 72 | + }, |
| 73 | +}); |
| 74 | +``` |
| 75 | + |
| 76 | +Let's update the Car details API route: |
| 77 | + |
| 78 | +_./src/routes/api/cars/$id.ts_ |
| 79 | + |
| 80 | +```ts |
| 81 | +import { cars } from '#db'; |
| 82 | +import { createFileRoute } from '@tanstack/react-router'; |
| 83 | +import { json } from '@tanstack/react-start'; |
| 84 | + |
| 85 | +export const Route = createFileRoute('/api/cars/$id')({ |
| 86 | + server: { |
| 87 | + handlers: { |
| 88 | + GET: async ({ params }) => { |
| 89 | + return json(cars.find((c) => c.id === params.id)); |
| 90 | + }, |
| 91 | + }, |
| 92 | + }, |
| 93 | +}); |
| 94 | +``` |
| 95 | + |
| 96 | +And finally, update the car booking API route: |
| 97 | + |
| 98 | +_./src/routes/api/cars/$id.ts_ |
| 99 | + |
| 100 | +```diff |
| 101 | +import { cars } from '#db'; |
| 102 | +import { createFileRoute } from '@tanstack/react-router'; |
| 103 | +import { json } from '@tanstack/react-start'; |
| 104 | + |
| 105 | +export const Route = createFileRoute('/api/cars/$id')({ |
| 106 | + server: { |
| 107 | + handlers: { |
| 108 | + GET: async ({ params }) => { |
| 109 | + return json(cars.find((c) => c.id === params.id)); |
| 110 | + }, |
| 111 | ++ PATCH: async ({ params, request }) => { |
| 112 | ++ const car = await request.json(); |
| 113 | ++ const index = cars.findIndex((c) => c.id === params.id); |
| 114 | ++ if (index !== -1) { |
| 115 | ++ cars[index] = { ...cars[index], isBooked: car.isBooked }; |
| 116 | ++ } |
| 117 | ++ return new Response(null, { status: 204 }); |
| 118 | ++ }, |
| 119 | + }, |
| 120 | + }, |
| 121 | +}); |
| 122 | + |
| 123 | +``` |
| 124 | + |
| 125 | +# About Basefactor + Lemoncode |
| 126 | + |
| 127 | +We are an innovating team of Javascript experts, passionate about turning your ideas into robust products. |
| 128 | + |
| 129 | +[Basefactor, consultancy by Lemoncode](http://www.basefactor.com) provides consultancy and coaching services. |
| 130 | + |
| 131 | +[Lemoncode](http://lemoncode.net/services/en/#en-home) provides training services. |
| 132 | + |
| 133 | +For the LATAM/Spanish audience we are running an Online Front End Master degree, more info: http://lemoncode.net/master-frontend |
0 commit comments