Skip to content
npm version

vtzacvite + nestjs

Next-generation full-stack solution

End-to-End Example
NestJS backend and frontend call example with end-to-end type safety.
typescript
@Controller('api/user')
export class UserController {
  @Post(':id/upload')
  async uploadAvatar(
    @Param('id') userId: string,
    @Query('version') version: string,
    @UploadedFile() file: Express.Multer.File,
    @Body() metadata: { title: string }
  ) {
    return {
      success: true,
      userId,
      version,
      filename: file.filename,
      metadata,
    };
  }
}
tsx
import { _http } from 'vtzac';
import { UserController } from './backend/user.controller';

const api = _http({
  ofetchOptions: { baseURL: 'http://localhost:3000' },
}).controller(UserController);

function UploadComponent() {
  const handleUpload = async (event: React.ChangeEvent<HTMLInputElement>) => {
    const file = event.target.files?.[0]; // File type
    if (!file) return;

    // Type-safe call
    // Actual request: POST /api/user/123/upload?version=v2
    const result = await api.uploadAvatar(
      '123', // @Param('id')
      'v2', // @Query('version')
      file as unknown as Express.Multer.File, // @UploadedFile()
      { title: 'Avatar' } // @Body()
    );

    console.log(result._data);
    // Output: { success: true, userId: '123', version: 'v2', filename: 'avatar.jpg', metadata: { title: 'Avatar' } }
  };

  return <input type="file" onChange={handleUpload} />;
}