PocketBase SDK使用:JavaScript、Dart客户端集成

【免费下载链接】pocketbase 开源的实时后端,仅用1个文件实现。 【免费下载链接】pocketbase 项目地址: https://gitcode.com/GitHub_Trending/po/pocketbase

概述

PocketBase是一个开源的Go后端框架,提供嵌入式SQLite数据库、实时订阅、文件管理、用户管理和RESTful API等功能。通过官方SDK客户端,开发者可以轻松地在JavaScript和Dart应用中集成PocketBase服务。

本文将详细介绍如何使用PocketBase的JavaScript和Dart SDK进行客户端集成,涵盖安装配置、基础操作、认证管理、实时订阅等核心功能。

环境准备

PocketBase服务端部署

首先需要部署PocketBase服务端:

# 下载最新版本
wget https://github.com/pocketbase/pocketbase/releases/download/v0.22.0/pocketbase_0.22.0_linux_amd64.zip
unzip pocketbase_0.22.0_linux_amd64.zip

# 启动服务
./pocketbase serve

服务启动后默认监听在http://127.0.0.1:8090

JavaScript SDK集成

安装与配置

# 使用npm安装
npm install pocketbase

# 或使用yarn
yarn add pocketbase

# 或使用pnpm
pnpm add pocketbase

基础使用示例

import PocketBase from 'pocketbase';

// 初始化客户端
const pb = new PocketBase('http://127.0.0.1:8090');

// 创建记录
async function createRecord() {
    const data = {
        title: "Hello World",
        content: "这是我的第一条记录",
        status: "published"
    };
    
    const record = await pb.collection('posts').create(data);
    console.log('创建成功:', record);
}

// 查询记录
async function getRecords() {
    const records = await pb.collection('posts').getFullList({
        sort: '-created',
        filter: 'status = "published"'
    });
    console.log('查询结果:', records);
}

// 更新记录
async function updateRecord(id) {
    const data = { title: "更新后的标题" };
    const record = await pb.collection('posts').update(id, data);
    console.log('更新成功:', record);
}

// 删除记录
async function deleteRecord(id) {
    await pb.collection('posts').delete(id);
    console.log('删除成功');
}

用户认证管理

// 用户注册
async function registerUser() {
    const userData = {
        email: "user@example.com",
        password: "securepassword123",
        passwordConfirm: "securepassword123",
        name: "张三"
    };
    
    const user = await pb.collection('users').create(userData);
    console.log('注册成功:', user);
}

// 用户登录
async function loginUser() {
    try {
        const authData = await pb.collection('users').authWithPassword(
            "user@example.com",
            "securepassword123"
        );
        console.log('登录成功:', authData);
    } catch (error) {
        console.error('登录失败:', error);
    }
}

// 获取当前用户
function getCurrentUser() {
    const user = pb.authStore.model;
    console.log('当前用户:', user);
    return user;
}

// 用户登出
function logoutUser() {
    pb.authStore.clear();
    console.log('已登出');
}

实时订阅功能

// 订阅集合变化
async function subscribeToCollection() {
    pb.collection('posts').subscribe('*', function(e) {
        console.log('实时事件:', e.action, e.record);
        
        switch(e.action) {
            case 'create':
                console.log('新记录创建:', e.record);
                break;
            case 'update':
                console.log('记录更新:', e.record);
                break;
            case 'delete':
                console.log('记录删除:', e.record.id);
                break;
        }
    });
}

// 取消订阅
function unsubscribeFromCollection() {
    pb.collection('posts').unsubscribe();
}

文件上传与管理

// 上传文件
async function uploadFile(fileInput) {
    const formData = new FormData();
    formData.append('file', fileInput.files[0]);
    
    const file = await pb.collection('posts').create({
        title: "带附件的文章",
        attachment: fileInput.files[0]
    });
    
    console.log('文件上传成功:', file);
}

// 获取文件URL
function getFileUrl(record, fieldName) {
    return pb.getFileUrl(record, record[fieldName]);
}

Dart SDK集成

安装与配置

pubspec.yaml中添加依赖:

dependencies:
  pocketbase: ^0.21.0

然后运行:

flutter pub get

基础使用示例

import 'package:pocketbase/pocketbase.dart';

final pb = PocketBase('http://127.0.0.1:8090');

// 创建记录
Future<void> createRecord() async {
  final data = {
    'title': 'Hello Dart',
    'content': '来自Dart客户端的记录',
    'status': 'published',
  };
  
  final record = await pb.collection('posts').create(body: data);
  print('创建成功: ${record.data}');
}

// 查询记录
Future<void> getRecords() async {
  final records = await pb.collection('posts').getFullList(
    sort: '-created',
    filter: 'status = "published"',
  );
  
  for (final record in records) {
    print('记录: ${record.data}');
  }
}

用户认证管理

// 用户注册
Future<void> registerUser() async {
  final userData = {
    'email': 'dartuser@example.com',
    'password': 'dartpassword123',
    'passwordConfirm': 'dartpassword123',
    'name': '李四',
  };
  
  final user = await pb.collection('users').create(body: userData);
  print('注册成功: ${user.data}');
}

// 用户登录
Future<void> loginUser() async {
  try {
    final authData = await pb.collection('users').authWithPassword(
      'dartuser@example.com',
      'dartpassword123',
    );
    print('登录成功: ${authData.record?.data}');
  } catch (e) {
    print('登录失败: $e');
  }
}

// 监听认证状态变化
void setupAuthListener() {
  pb.authStore.onChange.listen((token) {
    if (pb.authStore.isValid) {
      print('用户已认证: ${pb.authStore.model?.data}');
    } else {
      print('用户未认证');
    }
  });
}

实时订阅功能

// 订阅集合变化
Future<void> subscribeToCollection() async {
  final subscription = pb.collection('posts').subscribe('*', (e) {
    print('实时事件: ${e.action} - ${e.record?.data}');
    
    switch (e.action) {
      case 'create':
        print('新记录创建: ${e.record?.data}');
        break;
      case 'update':
        print('记录更新: ${e.record?.data}');
        break;
      case 'delete':
        print('记录删除: ${e.record?.id}');
        break;
    }
  });
  
  // 取消订阅
  // subscription.cancel();
}

高级功能与最佳实践

错误处理与重试机制

// JavaScript错误处理
async function safeOperation() {
    try {
        const result = await pb.collection('posts').getFirstListItem('status = "published"');
        return result;
    } catch (error) {
        if (error.status === 404) {
            console.log('记录不存在');
        } else if (error.status === 401) {
            console.log('认证失败,尝试重新登录');
            // 重新认证逻辑
        } else {
            console.error('操作失败:', error);
        }
        throw error;
    }
}

// 带重试的请求
async function withRetry(operation, maxRetries = 3) {
    for (let i = 0; i < maxRetries; i++) {
        try {
            return await operation();
        } catch (error) {
            if (i === maxRetries - 1) throw error;
            await new Promise(resolve => setTimeout(resolve, 1000 * (i + 1)));
        }
    }
}

批量操作优化

// 批量创建记录
async function batchCreateRecords(records) {
    const results = [];
    
    for (const record of records) {
        try {
            const result = await pb.collection('posts').create(record);
            results.push({ success: true, data: result });
        } catch (error) {
            results.push({ success: false, error: error.message });
        }
    }
    
    return results;
}

// 使用事务处理
async function transactionalOperations() {
    // PocketBase支持批量操作端点
    const batchData = {
        requests: [
            {
                method: 'POST',
                path: '/api/collections/posts/records',
                body: { title: '第一篇', content: '内容1' }
            },
            {
                method: 'POST', 
                path: '/api/collections/posts/records',
                body: { title: '第二篇', content: '内容2' }
            }
        ]
    };
    
    const result = await pb.send('/api/batch', {
        method: 'POST',
        body: batchData
    });
    
    return result;
}

性能优化建议

mermaid

安全最佳实践

认证安全

// 安全的认证处理
class SecureAuthManager {
    constructor(pbInstance) {
        this.pb = pbInstance;
        this.setupAuthListeners();
    }
    
    setupAuthListeners() {
        // 监听token过期
        this.pb.authStore.onChange(() => {
            if (!this.pb.authStore.isValid) {
                this.handleTokenExpired();
            }
        });
    }
    
    async handleTokenExpired() {
        try {
            // 尝试刷新token
            await this.pb.collection('users').authRefresh();
        } catch (error) {
            // 刷新失败,要求重新登录
            this.redirectToLogin();
        }
    }
    
    redirectToLogin() {
        // 跳转到登录页面
        console.log('请重新登录');
    }
    
    // 安全的登出
    async secureLogout() {
        try {
            await this.pb.collection('users').authRefresh();
            this.pb.authStore.clear();
        } catch (error) {
            this.pb.authStore.clear();
        }
    }
}

数据验证

// Dart数据验证示例
class PostValidator {
  static bool validateCreateData(Map<String, dynamic> data) {
    // 验证必填字段
    if (data['title'] == null || data['title'].toString().isEmpty) {
      throw Exception('标题不能为空');
    }
    
    if (data['content'] == null || data['content'].toString().isEmpty) {
      throw Exception('内容不能为空');
    }
    
    // 验证字段长度
    if (data['title'].toString().length > 100) {
      throw Exception('标题长度不能超过100字符');
    }
    
    return true;
  }
}

常见问题与解决方案

连接问题处理

// 连接状态监测
class ConnectionMonitor {
    constructor(pbInstance) {
        this.pb = pbInstance;
        this.isOnline = true;
        this.setupMonitoring();
    }
    
    setupMonitoring() {
        // 监听网络状态
        window.addEventListener('online', () => this.handleOnline());
        window.addEventListener('offline', () => this.handleOffline());
        
        // 定期检查连接
        setInterval(() => this.checkConnection(), 30000);
    }
    
    async checkConnection() {
        try {
            await this.pb.health.check();
            this.isOnline = true;
        } catch (error) {
            this.isOnline = false;
            console.warn('连接检查失败');
        }
    }
    
    handleOnline() {
        this.isOnline = true;
        console.log('网络连接恢复');
    }
    
    handleOffline() {
        this.isOnline = false;
        console.warn('网络连接断开');
    }
    
    // 带重试的请求
    async requestWithRetry(operation) {
        if (!this.isOnline) {
            throw new Error('网络连接不可用');
        }
        
        try {
            return await operation();
        } catch (error) {
            if (error.status === 0) {
                // 网络错误
                this.isOnline = false;
                throw new Error('网络请求失败');
            }
            throw error;
        }
    }
}

内存管理

// Dart内存管理
class PbService {
  final PocketBase pb;
  final List<RealtimeSubscription> _subscriptions = [];
  
  PbService(String url) : pb = PocketBase(url);
  
  // 添加订阅并管理生命周期
  RealtimeSubscription subscribeWithManagement(String collection, String filter, Function callback) {
    final subscription = pb.collection(collection).subscribe(filter, callback);
    _subscriptions.add(subscription);
    return subscription;
  }
  
  // 清理所有订阅
  void dispose() {
    for (final subscription in _subscriptions) {
      subscription.cancel();
    }
    _subscriptions.clear();
  }
  
  // 自动取消订阅
  void autoUnsubscribe(RealtimeSubscription subscription, Duration duration) {
    Future.delayed(duration, () {
      if (_subscriptions.contains(subscription)) {
        subscription.cancel();
        _subscriptions.remove(subscription);
      }
    });
  }
}

总结

PocketBase的JavaScript和Dart SDK提供了强大的客户端集成能力,使得开发者可以轻松地在各种应用中集成后端服务。通过本文的介绍,您应该能够:

  1. 快速上手:掌握SDK的安装和基础使用方法
  2. 深入理解:了解认证管理、实时订阅等高级功能
  3. 优化实践:应用性能优化和安全最佳实践
  4. 解决问题:处理常见的连接和内存管理问题

无论是Web应用、移动应用还是桌面应用,PocketBase SDK都能提供稳定可靠的后端服务集成方案。随着项目的不断发展,建议持续关注官方文档和更新,以获取最新的功能和优化。

【免费下载链接】pocketbase 开源的实时后端,仅用1个文件实现。 【免费下载链接】pocketbase 项目地址: https://gitcode.com/GitHub_Trending/po/pocketbase

更多推荐