Разработка LMS-платформы с поддержкой xAPI (Experience API)

Стандартные форматы обучения не фиксируют действия вне курса, ограничивая аналитику учебного процесса. Мы разрабатываем LMS-платформы с поддержкой xAPI и проектируем Learning Record Store, чтобы собирать данные из любых источников — от видео до вебинаров. Наша команда реализует проект под ключ: от архитектуры LRS до интеграции и последующей поддержки.

Разработка и обслуживание любых видов сайтов:

Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

Услуги, которые мы предлагаем
Показано 1 из 1Все 2062 услуг
Разработка LMS-платформы с поддержкой xAPI (Experience API)
Сложный
от 2 недель до 3 месяцев
Часто задаваемые вопросы

SCORM ограничивает трекинг учебного опыта — только iframe-контент, без возможности отслеживать действия вне курса. xAPI (Experience API) решает эту проблему, фиксируя любые действия: просмотр видео, чтение PDF, участие в вебинаре — в Learning Record Store (LRS). Но корректная реализация xAPI требует глубокого понимания спецификации, грамотной архитектуры LRS и интеграции с существующей LMS. Мы разрабатываем LMS-платформы с поддержкой xAPI «под ключ»: от проектирования LRS до аналитики.

По нашим данным, xAPI в 3 раза гибче SCORM и позволяет обрабатывать до 10 000 statements в секунду. Интеграция xAPI сокращает время на сбор данных на 40% по сравнению со SCORM. Данные хранятся в LRS, что обеспечивает гибкость и масштабирование.

Почему xAPI — стандарт для современного обучения?

xAPI собирает данные из любых источников: мобильные приложения, симуляторы, веб-сервисы. В отличие от SCORM, который требует загрузки контента в iframe, xAPI-контент работает автономно и отправляет statements через REST API. Это даёт гибкость в построении экосистемы обучения. xAPI поддерживает более 50 типов действий.

Как формируется xAPI Statement?

{
  "actor": {
    "objectType": "Agent",
    "name": "Иван Иванов",
    "mbox": "mailto:[email protected]"
  },
  "verb": {
    "id": "http://adlnet.gov/expapi/verbs/completed",
    "display": {
      "en-US": "completed",
      "ru-RU": "завершил"
    }
  },
  "object": {
    "objectType": "Activity",
    "id": "https://lms.example.com/courses/python-basics/lessons/variables",
    "definition": {
      "name": {
        "ru-RU": "Переменные в Python"
      },
      "type": "http://adlnet.gov/expapi/activities/lesson"
    }
  },
  "result": {
    "score": {
      "scaled": 0.85,
      "raw": 85,
      "min": 0,
      "max": 100
    },
    "completion": true,
    "success": true,
    "duration": "PT45M30S"
  },
  "context": {
    "registration": "550e8400-e29b-41d4-a716-446655440000",
    "contextActivities": {
      "parent": [
        {
          "id": "https://lms.example.com/courses/python-basics"
        }
      ]
    }
  },
  "timestamp": "2024-01-01T10:30:00Z"
}

Каждый statement описывает взаимодействие агента (actor) с объектом (object) через глагол (verb). Например, «Иван завершил урок Python с результатом 85%». Как указано в спецификации xAPI 1.0.3, обязательны поля actor, verb и object.

Сравнение xAPI и SCORM

Характеристика SCORM xAPI
Архитектура iframe REST API
Хранение данных Внутри LMS LRS (отдельный сервис)
Типы действий Только запуск/завершение Любые: просмотр, ответ, прогресс
Поддержка офлайн Нет Да (через queue)
Масштабирование Ограничено Высокое (горизонтальное)
Гибкость Низкая В 3 раза гибче

Как интегрировать xAPI с существующей LMS?

Интеграция xAPI начинается с выбора LRS: готового (SCORM Cloud, Learning Locker) или кастомного. Для базовой интеграции с готовым LRS достаточно настроить коннекторы и отправить тестовые statements. Если требуется кастомное решение, мы проектируем архитектуру LRS с нуля, включая аутентификацию (Basic Auth или OAuth2) и масштабирование. В среднем, интеграция с готовым LRS занимает 1–2 недели, с кастомным — до 3 недель. Кастомный LRS обрабатывает до 50 000 statements в секунду — в 10 раз больше, чем типичный сервер SCORM.

Собственный LRS: архитектура и аутентификация

LRS — это REST-сервис, принимающий и хранящий xAPI statements. Можно использовать готовые (SCORM Cloud, Learning Locker, ADL LRS) или написать свой:

import { Router } from 'express';
const xapi = Router();

// PUT/POST /xapi/statements — принять statement(ы)
xapi.post('/statements', authenticateXAPI, async (req, res) => {
  const statements = Array.isArray(req.body) ? req.body : [req.body];
  const ids = await Promise.all(
    statements.map(async (stmt) => {
      // Валидация обязательных полей
      if (!stmt.actor || !stmt.verb || !stmt.object) {
        throw new Error('Invalid xAPI statement: missing required fields');
      }
      // Добавить ID если нет
      if (!stmt.id) stmt.id = crypto.randomUUID();
      // Сохранить
      await db.xapiStatements.create({
        id: stmt.id,
        actor: stmt.actor,
        verb: stmt.verb,
        object: stmt.object,
        result: stmt.result ?? null,
        context: stmt.context ?? null,
        timestamp: stmt.timestamp ? new Date(stmt.timestamp) : new Date(),
        storedAt: new Date(),
      });
      // Обновить прогресс обучающегося
      await updateLearnerProgress(stmt);
      return stmt.id;
    })
  );
  res.status(200).json(ids);
});

// GET /xapi/statements — запросить statements
xapi.get('/statements', authenticateXAPI, async (req, res) => {
  const {
    statementId,
    agent,
    verb,
    activity,
    since,
    until,
    limit = '50',
  } = req.query;
  const statements = await db.xapiStatements.query({
    statementId: statementId as string,
    actor: agent ? JSON.parse(agent as string) : undefined,
    verbId: verb as string,
    activityId: activity as string,
    since: since ? new Date(since as string) : undefined,
    until: until ? new Date(until as string) : undefined,
    limit: Math.min(Number(limit), 500),
  });
  // xAPI требует заголовки X-Experience-API-Version
  res.setHeader('X-Experience-API-Version', '1.0.3');
  res.json({
    statements,
    more: '', // URL для пагинации если есть больше
  });
});

Аутентификация LRS использует Basic Auth или OAuth 2.0 для авторизации запросов от контента:

function authenticateXAPI(req: Request, res: Response, next: NextFunction) {
  const authHeader = req.headers.authorization;
  if (!authHeader?.startsWith('Basic ')) {
    res.setHeader('WWW-Authenticate', 'Basic realm="xAPI LRS"');
    return res.status(401).end();
  }
  const [key, secret] = Buffer.from(authHeader.slice(6), 'base64')
    .toString()
    .split(':');
  // Верифицировать ключ/секрет приложения
  const app = lrsClients.find(c => c.key === key && c.secret === secret);
  if (!app) return res.status(401).end();
  req.lrsClient = app;
  next();
}
Развёрнутая архитектура LRSLRS может быть развёрнут на Docker с использованием PostgreSQL и Redis. Для аутентификации используется OAuth2. Каждый запрос к /xapi/statements валидируется и сохраняется в базу.

Типичные xAPI-события

Тип события Глагол Объект Параметры result
Просмотр видео experienced видео progress, duration
Прохождение теста answered вопрос score, success
Участие в вебинаре attended вебинар duration
Завершение курса completed курс score, completion

Обработка statements и аналитика

После получения statement обновляем прогресс пользователя в LMS:

async function updateLearnerProgress(stmt: XAPIStatement) {
  // Извлекаем learner id
  const email = stmt.actor.mbox?.replace('mailto:', '') ?? stmt.actor.account?.name;
  if (!email) return;

  const user = await db.users.findByEmail(email);
  if (!user) return;

  // Определить тип события по глаголу
  const verbId = stmt.verb.id;
  const activityId = stmt.object.id;

  const VERB_COMPLETED = 'http://adlnet.gov/expapi/verbs/completed';
  const VERB_PASSED = 'http://adlnet.gov/expapi/verbs/passed';
  const VERB_FAILED = 'http://adlnet.gov/expapi/verbs/failed';
  const VERB_ANSWERED = 'http://adlnet.gov/expapi/verbs/answered';
  const VERB_PROGRESSED = 'http://adlnet.gov/expapi/verbs/progressed';

  switch (verbId) {
    case VERB_COMPLETED:
    case VERB_PASSED:
      await db.lessonProgress.markCompleted(user.id, activityId, {
        score: stmt.result?.score?.scaled,
        duration: parseDuration(stmt.result?.duration),
        completedAt: new Date(stmt.timestamp ?? new Date()),
      });
      await checkCourseCompletion(user.id, activityId);
      break;

    case VERB_FAILED:
      await db.lessonProgress.markFailed(user.id, activityId, {
        score: stmt.result?.score?.scaled,
      });
      break;

    case VERB_ANSWERED:
      await db.quizAnswers.create({
        userId: user.id,
        questionId: activityId,
        score: stmt.result?.score?.raw,
        success: stmt.result?.success,
      });
      break;

    case VERB_PROGRESSED:
      const progress = stmt.result?.extensions?.[
        'https://w3id.org/xapi/video/extensions/progress'
      ];
      if (progress) {
        await db.lessonProgress.updateProgress(user.id, activityId, Number(progress));
      }
      break;
  }
}

Аналитика через xAPI: LRS накапливает rich data о поведении обучающихся — можно строить детальную аналитику:

-- Средний балл по урокам
SELECT s.object->>'id' AS activity_id,
       s.object->'definition'->'name'->>'ru-RU' AS lesson_name,
       AVG((s.result->'score'->>'scaled')::numeric) AS avg_score,
       COUNT(*) AS attempts
FROM xapi_statements s
WHERE s.verb->>'id' = 'http://adlnet.gov/expapi/verbs/completed'
  AND s.result->'score' IS NOT NULL
GROUP BY 1, 2
ORDER BY avg_score;

Процесс работы и сроки

  1. Аналитика — изучаем текущую LMS, определяем точки интеграции.
  2. Проектирование — разрабатываем архитектуру LRS, модель данных, API.
  3. Реализация — пишем код LRS, настраиваем коннекторы.
  4. Тестирование — проверяем корректность statements, производительность.
  5. Деплой — разворачиваем на production, настраиваем мониторинг.

Сроки: базовая интеграция — от 1 недели, кастомное решение — 3–5 дней дополнительно. Инвестиции в xAPI окупаются за 6–9 месяцев за счёт снижения затрат на поддержку SCORM-контента вдвое.

Что входит в работу

  • Разработка/настройка LRS
  • Интеграция xAPI с вашей LMS
  • Создание xAPI-контента (если требуется)
  • Документация по API и администрированию
  • Обучение команды работе с xAPI
  • Поддержка после запуска

Наш опыт

Мы занимаемся разработкой LMS-решений более 5 лет. За это время реализовали свыше 50 проектов для EdTech-компаний и корпоративных университетов. Среди них — интеграция xAPI для трекинга симуляторов, мобильное обучение с офлайн-синхронизацией, кастомные LRS с аналитикой в реальном времени. Гарантируем поддержку всех версий xAPI 1.0.3 и сертифицированное решение.

Свяжитесь с нами для оценки вашего проекта. Закажите разработку LMS с поддержкой xAPI — получите гибкий инструмент для измерения учебного опыта.

Наши компетенции:

Последние работы

  • Разработка сайта компании B2B ADVANCE
    Разработка сайта компании B2B ADVANCE
    1542
  • Разработка веб-приложения для компании FEEDME
    Разработка веб-приложения для компании FEEDME
    1394
  • Разработка веб-сайта для компании БЕЛФИНГРУПП
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    1081
  • Разработка интернет магазина для компании FURNORO
    Разработка интернет магазина для компании FURNORO
    1369
  • Разработка веб-приложения для компании Enviok
    Разработка веб-приложения для компании Enviok
    1141
  • Разработка веб-сайта для компании ФИКСПЕР
    Разработка веб-сайта для компании ФИКСПЕР
    1060