Примеры использования
Практические примеры использования EMD Cloud SDK для решения типовых задач.
Авторизация
Полный цикл авторизации
import { EmdCloud, AppEnvironment } from '@emd-cloud/sdk';
const emdCloud = new EmdCloud({
environment: AppEnvironment.Client,
appId: 'your-app-id'
});
// Регистрация
async function registerUser(email, password, name) {
try {
const user = await emdCloud.auth.register({
email,
password,
name
});
localStorage.setItem('auth_token', user.token);
return user;
} catch (error) {
console.error('Ошибка регистрации:', error);
throw error;
}
}
// Вход
async function loginUser(email, password) {
try {
const user = await emdCloud.auth.login({
login: email,
password
});
localStorage.setItem('auth_token', user.token);
return user;
} catch (error) {
console.error('Ошибка входа:', error);
throw error;
}
}
// Проверка авторизации
async function checkAuth() {
const token = localStorage.getItem('auth_token');
if (!token) {
return null;
}
emdCloud.setAuthToken(token);
try {
const user = await emdCloud.auth.authorization();
return user;
} catch (error) {
localStorage.removeItem('auth_token');
return null;
}
}
// Выход
async function logoutUser() {
try {
await emdCloud.auth.logout();
localStorage.removeItem('auth_token');
} catch (error) {
console.error('Ошибка выхода:', error);
}
}
База данных
CRUD приложение
class ProductManager {
constructor(emdCloud, collectionId) {
this.db = emdCloud.database(collectionId);
}
// Получить все продукты
async getProducts(filters = {}) {
const query = {};
if (filters.category) {
query["$and"] = [
{ "data.category": { "$eq": filters.category } }
];
}
if (filters.minPrice) {
query["$and"] = query["$and"] || [];
query["$and"].push({
"data.price": { "$gte": filters.minPrice }
});
}
const result = await this.db.getRows({
query: Object.keys(query).length > 0 ? query : undefined,
sort: [{ column: "createdAt", sort: "desc" }],
limit: 50,
useHumanReadableNames: true
});
return result.data;
}
// Создать продукт
async createProduct(productData) {
const result = await this.db.createRow(productData, {
notice: 'Создан новый продукт'
});
return result;
}
// Обновить продукт
async updateProduct(productId, updates) {
const result = await this.db.updateRow(
productId,
updates,
{
notice: 'Обновлен продукт',
saveMode: 'SYNC'
}
);
return result;
}
// Удалить продукт
async deleteProduct(productId) {
await this.db.deleteRow(productId);
}
// Поиск продуктов
async searchProducts(searchTerm) {
const result = await this.db.getRows({
search: searchTerm,
limit: 20,
useHumanReadableNames: true
});
return result.data;
}
}
// Использование
const productManager = new ProductManager(emdCloud, 'products-collection-id');
// Получить все продукты категории "electronics"
const electronics = await productManager.getProducts({
category: 'electronics',
minPrice: 1000
});
// Создать новый продукт
const newProduct = await productManager.createProduct({
name: 'Ноутбук',
price: 50000,
category: 'electronics',
inStock: true
});
// Обновить продукт
await productManager.updateProduct(newProduct._id, {
price: 45000,
discount: 10
});
// Поиск
const results = await productManager.searchProducts('ноутбук');
Чаты
Real-time чат приложение
class ChatApplication {
constructor(emdCloud) {
this.emdCloud = emdCloud;
this.chatWs = null;
this.currentChannel = null;
this.messageHandlers = [];
}
// Инициализация
async init() {
this.chatWs = this.emdCloud.chatWebSocket({
autoReconnect: true,
callbacks: {
onMessageReceived: (message) => {
this.handleNewMessage(message);
},
onConnectionStateChange: (state) => {
console.log('Connection state:', state);
}
}
});
await this.chatWs.connect();
}
// Получить список каналов
async getChannels() {
const result = await this.emdCloud.chat.listChannels({
type: ChatChannelType.Public,
limit: 50
});
return result.data;
}
// Открыть канал
async openChannel(channelId) {
// Отписаться от предыдущего канала
if (this.currentChannel) {
this.chatWs.unsubscribeFromChannel(this.currentChannel);
}
// Подписаться на новый канал
await this.chatWs.subscribeToChannel(channelId);
this.currentChannel = channelId;
// Загрузить историю сообщений
const messages = await this.emdCloud.chat.listMessages(channelId, {
limit: 50,
page: 0
});
return messages.data;
}
// Отправить сообщение
async sendMessage(text, attachments = []) {
await this.emdCloud.chat.sendMessage(this.currentChannel, {
message: text,
attaches: attachments
});
}
// Обработка новых сообщений
handleNewMessage(message) {
if (message.channel === this.currentChannel) {
this.messageHandlers.forEach(handler => handler(message));
}
}
// Подписка на новые сообщения
onMessage(handler) {
this.messageHandlers.push(handler);
}
// Отключение
disconnect() {
if (this.chatWs) {
this.chatWs.disconnect();
}
}
}
// Использование
const chat = new ChatApplication(emdCloud);
await chat.init();
// Получить каналы
const channels = await chat.getChannels();
// Открыть канал
const messages = await chat.openChannel(channels[0].id);
// Подписаться на новые сообщения
chat.onMessage((message) => {
console.log('Новое сообщение:', message.message);
// Обновить UI
});
// Отправить сообщение
await chat.sendMessage('Привет всем!');
Загрузка файлов
Загрузка с прогресс-баром
class FileUploadManager {
constructor(emdCloud) {
this.emdCloud = emdCloud;
this.uploads = new Map();
}
async uploadFile(file, onProgress) {
const uploadId = this.generateId();
this.uploads.set(uploadId, {
file,
progress: 0,
status: 'uploading'
});
try {
const result = await this.emdCloud.uploader.upload(file, {
onProgress: (uploaded, total) => {
const progress = Math.round((uploaded / total) * 100);
this.updateProgress(uploadId, progress);
onProgress?.(progress);
},
onSuccess: () => {
this.updateStatus(uploadId, 'completed');
},
onError: (error) => {
this.updateStatus(uploadId, 'error');
console.error('Upload error:', error);
}
});
return result;
} catch (error) {
this.updateStatus(uploadId, 'error');
throw error;
}
}
async uploadMultiple(files, onProgress) {
const uploads = Array.from(files).map((file, index) => {
return this.uploadFile(file, (progress) => {
onProgress?.(index, progress);
});
});
return Promise.all(uploads);
}
updateProgress(id, progress) {
const upload = this.uploads.get(id);
if (upload) {
upload.progress = progress;
}
}
updateStatus(id, status) {
const upload = this.uploads.get(id);
if (upload) {
upload.status = status;
}
}
generateId() {
return `upload-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
}
}
// Использование
const uploader = new FileUploadManager(emdCloud);
// Загрузка одного файла
const file = document.querySelector('input[type="file"]').files[0];
const result = await uploader.uploadFile(file, (progress) => {
console.log(`Прогресс: ${progress}%`);
document.getElementById('progress').value = progress;
});
console.log('Файл загружен:', result.url);
// Загрузка нескольких файлов
const files = document.querySelector('input[type="file"][multiple]').files;
const results = await uploader.uploadMultiple(files, (index, progress) => {
console.log(`Файл ${index + 1}: ${progress}%`);
});
React приложение
Полное приложение с авторизацией и данными
import { ApplicationProvider, useAuth, useDatabase } from '@emd-cloud/react-components';
import { useState, useEffect } from 'react';
// Главный компонент приложения
function App() {
return (
<ApplicationProvider app="your-app-id">
<Main />
</ApplicationProvider>
);
}
// Основной компонент
function Main() {
const { user, loading } = useAuth();
if (loading) {
return <div>Загрузка...</div>;
}
return user ? <Dashboard /> : <AuthPage />;
}
// Страница авторизации
function AuthPage() {
const [isLogin, setIsLogin] = useState(true);
return (
<div className="auth-page">
<h1>EMD Cloud App</h1>
{isLogin ? <LoginForm /> : <RegisterForm />}
<button onClick={() => setIsLogin(!isLogin)}>
{isLogin ? 'Нет аккаунта? Зарегистрироваться' : 'Есть аккаунт? Войти'}
</button>
</div>
);
}
// Форма входа
function LoginForm() {
const { login } = useAuth();
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const handleSubmit = async (e) => {
e.preventDefault();
await login({ login: email, password });
};
return (
<form onSubmit={handleSubmit}>
<input
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
placeholder="Email"
required
/>
<input
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
placeholder="Пароль"
required
/>
<button type="submit">Войти</button>
</form>
);
}
// Форма регистрации
function RegisterForm() {
const { register } = useAuth();
const [formData, setFormData] = useState({
email: '',
password: '',
name: ''
});
const handleSubmit = async (e) => {
e.preventDefault();
await register(formData);
};
return (
<form onSubmit={handleSubmit}>
<input
value={formData.name}
onChange={(e) => setFormData({ ...formData, name: e.target.value })}
placeholder="Имя"
required
/>
<input
type="email"
value={formData.email}
onChange={(e) => setFormData({ ...formData, email: e.target.value })}
placeholder="Email"
required
/>
<input
type="password"
value={formData.password}
onChange={(e) => setFormData({ ...formData, password: e.target.value })}
placeholder="Пароль"
required
/>
<button type="submit">Зарегистрироваться</button>
</form>
);
}
// Dashboard
function Dashboard() {
const { user, logout } = useAuth();
return (
<div className="dashboard">
<header>
<h1>Привет, {user.name}!</h1>
<button onClick={logout}>Выйти</button>
</header>
<ProductList />
</div>
);
}
// Список продуктов
function ProductList() {
const { getRows, createRow } = useDatabase('products');
const [products, setProducts] = useState([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
loadProducts();
}, []);
async function loadProducts() {
const result = await getRows({
limit: 50,
useHumanReadableNames: true
});
setProducts(result.data);
setLoading(false);
}
async function addProduct(productData) {
const newProduct = await createRow(productData);
setProducts([...products, newProduct]);
}
if (loading) return <div>Загрузка продуктов...</div>;
return (
<div>
<h2>Продукты</h2>
<AddProductForm onAdd={addProduct} />
<div className="products">
{products.map(product => (
<div key={product._id} className="product">
<h3>{product.name}</h3>
<p>{product.price} ₽</p>
</div>
))}
</div>
</div>
);
}
// Форма добавления продукта
function AddProductForm({ onAdd }) {
const [formData, setFormData] = useState({ name: '', price: 0 });
const handleSubmit = async (e) => {
e.preventDefault();
await onAdd(formData);
setFormData({ name: '', price: 0 });
};
return (
<form onSubmit={handleSubmit}>
<input
value={formData.name}
onChange={(e) => setFormData({ ...formData, name: e.target.value })}
placeholder="Название"
required
/>
<input
type="number"
value={formData.price}
onChange={(e) => setFormData({ ...formData, price: Number(e.target.value) })}
placeholder="Цена"
required
/>
<button type="submit">Добавить</button>
</form>
);
}
export default App;
Best Practices
Обработка ошибок
async function safeApiCall(apiFunction, errorMessage) {
try {
return await apiFunction();
} catch (error) {
console.error(errorMessage, error);
// Показать уведомление пользователю
showNotification({
type: 'error',
message: errorMessage
});
// Логирование в сервис мониторинга
logError(error);
throw error;
}
}
Кеширование данных
class DataCache {
constructor(ttl = 5 * 60 * 1000) { // 5 минут
this.cache = new Map();
this.ttl = ttl;
}
set(key, value) {
this.cache.set(key, {
value,
timestamp: Date.now()
});
}
get(key) {
const item = this.cache.get(key);
if (!item) return null;
if (Date.now() - item.timestamp > this.ttl) {
this.cache.delete(key);
return null;
}
return item.value;
}
clear() {
this.cache.clear();
}
}
const cache = new DataCache();
async function getProductsWithCache() {
const cached = cache.get('products');
if (cached) {
return cached;
}
const products = await productsDb.getRows({ limit: 50 });
cache.set('products', products);
return products;
}
Следующие шаги
- 🤝 Узнайте как внести вклад
- 📚 Вернитесь к обзору SDK
- 🚀 Создайте проект с Create App