UNPKG

@ddl-tech/wappler-pocketbase

Version:

PocketBase CRUD module for Wappler Server Connect with complete database operations, authentication, and file management

543 lines (501 loc) 12.6 kB
# PocketBase Module Usage Examples This file contains practical examples of how to use the PocketBase CRUD module in Wappler Server Connect. ## Example 1: Basic Blog System ### Step 1: Setup Connection Create a Server Action called `pb_connect.json`: ```json { "meta": { "options": { "linkedFile": "/api/pb_connect", "linkedForm": "pb_connect" }, "$_GET": [ { "type": "text", "name": "test" } ] }, "exec": { "steps": [ { "name": "connect", "module": "pocketbase", "action": "connect", "options": { "url": "http://127.0.0.1:8090" }, "output": true } ] } } ``` ### Step 2: User Authentication Create `pb_auth.json`: ```json { "meta": { "options": { "linkedFile": "/api/pb_auth", "linkedForm": "pb_auth" }, "$_POST": [ { "type": "text", "name": "email" }, { "type": "text", "name": "password" } ] }, "exec": { "steps": [ { "name": "authenticate", "module": "pocketbase", "action": "authenticate", "options": { "email": "{{$_POST.email}}", "password": "{{$_POST.password}}", "collection": "users" }, "output": true } ] } } ``` ### Step 3: Create Blog Post Create `pb_create_post.json`: ```json { "meta": { "options": { "linkedFile": "/api/pb_create_post", "linkedForm": "pb_create_post" }, "$_POST": [ { "type": "text", "name": "title" }, { "type": "text", "name": "content" }, { "type": "text", "name": "category" } ], "$_FILES": [ { "type": "file", "name": "featured_image" } ] }, "exec": { "steps": [ { "name": "create_post", "module": "pocketbase", "action": "create", "options": { "collection": "posts", "data": { "title": "{{$_POST.title}}", "content": "{{$_POST.content}}", "category": "{{$_POST.category}}", "featured_image": "{{$_FILES.featured_image.path}}", "author": "{{$_SESSION.pb_user.id}}", "status": "draft", "created": "{{NOW()}}" } }, "output": true } ] } } ``` ### Step 4: Get Blog Posts Create `pb_get_posts.json`: ```json { "meta": { "options": { "linkedFile": "/api/pb_get_posts" }, "$_GET": [ { "type": "text", "name": "page" }, { "type": "text", "name": "category" }, { "type": "text", "name": "search" } ] }, "exec": { "steps": [ { "name": "get_posts", "module": "pocketbase", "action": "getList", "options": { "collection": "posts", "page": "{{$_GET.page || 1}}", "perPage": "10", "filter": "{{($_GET.category ? 'category = \"' + $_GET.category + '\"' : '') + ($_GET.search ? ($_GET.category ? ' && ' : '') + 'title ~ \"' + $_GET.search + '\"' : '') + (($_GET.category || $_GET.search) ? ' && ' : '') + 'status = \"published\"'}}", "sort": "-created", "expand": "author,category" }, "output": true } ] } } ``` ### Step 5: Update Blog Post Create `pb_update_post.json`: ```json { "meta": { "options": { "linkedFile": "/api/pb_update_post", "linkedForm": "pb_update_post" }, "$_POST": [ { "type": "text", "name": "id" }, { "type": "text", "name": "title" }, { "type": "text", "name": "content" }, { "type": "text", "name": "status" } ] }, "exec": { "steps": [ { "name": "update_post", "module": "pocketbase", "action": "update", "options": { "collection": "posts", "id": "{{$_POST.id}}", "data": { "title": "{{$_POST.title}}", "content": "{{$_POST.content}}", "status": "{{$_POST.status}}", "updated": "{{NOW()}}" } }, "output": true } ] } } ``` ## Example 2: E-commerce Product Management ### Get Products with Advanced Filtering ```json { "name": "get_products", "module": "pocketbase", "action": "getList", "options": { "collection": "products", "page": "{{$_GET.page || 1}}", "perPage": "20", "filter": "{{(function() { var filters = []; if ($_GET.category) filters.push('category = \"' + $_GET.category + '\"'); if ($_GET.min_price) filters.push('price >= ' + $_GET.min_price); if ($_GET.max_price) filters.push('price <= ' + $_GET.max_price); if ($_GET.in_stock) filters.push('stock > 0'); if ($_GET.search) filters.push('(name ~ \"' + $_GET.search + '\" || description ~ \"' + $_GET.search + '\")'); return filters.join(' && '); })()}}", "sort": "{{$_GET.sort || '-created'}}", "expand": "category,images" }, "output": true } ``` ### Batch Update Product Inventory ```json { "name": "batch_update_inventory", "module": "pocketbase", "action": "batch", "options": { "operations": "{{$_POST.inventory_updates.map(function(item) { return { type: 'update', collection: 'products', id: item.product_id, data: { stock: item.new_stock, updated: NOW() } }; })}}" }, "output": true } ``` ## Example 3: User Profile Management ### Get User Profile with Relations ```json { "name": "get_user_profile", "module": "pocketbase", "action": "getOne", "options": { "collection": "users", "id": "{{$_SESSION.pb_user.id}}", "expand": "profile,orders,favorites" }, "output": true } ``` ### Update User Profile with Avatar ```json { "name": "update_profile", "module": "pocketbase", "action": "update", "options": { "collection": "users", "id": "{{$_SESSION.pb_user.id}}", "data": { "name": "{{$_POST.name}}", "bio": "{{$_POST.bio}}", "avatar": "{{$_FILES.avatar ? $_FILES.avatar.path : undefined}}", "updated": "{{NOW()}}" } }, "output": true } ``` ## Example 4: File Management ### Upload Multiple Files ```json { "name": "upload_gallery", "module": "pocketbase", "action": "create", "options": { "collection": "gallery", "data": { "title": "{{$_POST.title}}", "description": "{{$_POST.description}}", "images": "{{Object.keys($_FILES).filter(key => key.startsWith('image_')).map(key => $_FILES[key].path)}}", "user": "{{$_SESSION.pb_user.id}}" } }, "output": true } ``` ### Get File URLs for Gallery ```json { "name": "get_gallery_urls", "module": "pocketbase", "action": "getFileUrl", "options": { "collection": "gallery", "recordId": "{{$_GET.gallery_id}}", "filename": "{{$_GET.filename}}", "thumb": "{{$_GET.size || '300x200'}}" }, "output": true } ``` ## Example 5: Real-time Data with Health Checks ### Health Check Endpoint ```json { "meta": { "options": { "linkedFile": "/api/health" } }, "exec": { "steps": [ { "name": "health_check", "module": "pocketbase", "action": "healthCheck", "options": {}, "output": true }, { "name": "get_collections", "module": "pocketbase", "action": "getCollections", "options": {}, "output": true } ] } } ``` ## Example 6: Advanced Search ### Full-text Search Across Multiple Collections ```json { "name": "global_search", "module": "pocketbase", "action": "batch", "options": { "operations": [ { "type": "getList", "collection": "posts", "options": { "filter": "title ~ '{{$_GET.query}}' || content ~ '{{$_GET.query}}'", "fields": "id,title,content,created", "perPage": 5 } }, { "type": "getList", "collection": "products", "options": { "filter": "name ~ '{{$_GET.query}}' || description ~ '{{$_GET.query}}'", "fields": "id,name,description,price", "perPage": 5 } }, { "type": "getList", "collection": "users", "options": { "filter": "name ~ '{{$_GET.query}}' || bio ~ '{{$_GET.query}}'", "fields": "id,name,bio,avatar", "perPage": 5 } } ] }, "output": true } ``` ## Frontend Integration Examples ### JavaScript Fetch Examples ```javascript // Authenticate user async function loginUser(email, password) { const response = await fetch('/api/pb_auth', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ email, password }) }); const result = await response.json(); if (result.authenticate.success) { console.log('User logged in:', result.authenticate.user); return result.authenticate; } else { throw new Error('Login failed'); } } // Get posts with pagination async function getPosts(page = 1, category = null, search = null) { const params = new URLSearchParams({ page }); if (category) params.append('category', category); if (search) params.append('search', search); const response = await fetch(`/api/pb_get_posts?${params}`); const result = await response.json(); return result.get_posts; } // Create new post async function createPost(postData, featuredImage) { const formData = new FormData(); Object.keys(postData).forEach(key => { formData.append(key, postData[key]); }); if (featuredImage) { formData.append('featured_image', featuredImage); } const response = await fetch('/api/pb_create_post', { method: 'POST', body: formData }); const result = await response.json(); return result.create_post; } ``` ### App Connect Data Bindings ```html <!-- Display posts list --> <div dmx-repeat:posts="serverconnect1.data.get_posts.items"> <div class="card mb-3"> <div class="card-body"> <h5 class="card-title">{{title}}</h5> <p class="card-text">{{content.substr(0, 150)}}...</p> <small class="text-muted"> By {{expand.author.name}} on {{created.formatDate('MMM dd, yyyy')}} </small> </div> </div> </div> <!-- Pagination --> <nav> <ul class="pagination"> <li class="page-item" dmx-class:disabled="serverconnect1.data.get_posts.page == 1"> <a class="page-link" href="#" dmx-on:click="serverconnect1.load({page: serverconnect1.data.get_posts.page - 1})">Previous</a> </li> <li class="page-item" dmx-class:disabled="serverconnect1.data.get_posts.page == serverconnect1.data.get_posts.totalPages"> <a class="page-link" href="#" dmx-on:click="serverconnect1.load({page: serverconnect1.data.get_posts.page + 1})">Next</a> </li> </ul> </nav> ``` ## Error Handling Examples ### Server Action with Error Handling ```json { "exec": { "steps": [ { "name": "try_create_post", "module": "core", "action": "trycatch", "options": { "try": [ { "name": "create_post", "module": "pocketbase", "action": "create", "options": { "collection": "posts", "data": "{{$_POST}}" } } ], "catch": [ { "name": "error_response", "module": "core", "action": "response", "options": { "status": 400, "data": { "error": true, "message": "Failed to create post: {{$_ERROR.message}}" } } } ] }, "output": true } ] } } ```