Введение

Что такое mockly

Бесплатный фейковый REST API для фронтенда и прототипов. Заводишь проект, кладёшь в коллекцию JSON — получаешь полноценные CRUD-эндпоинты с фильтрами, сортировкой, пагинацией и связями. По умолчанию ни ключей, ни заголовков: моки открыты по публичной ссылке; включи авторизацию, когда нужны приватные ресурсы.

Базовый адрес
https://api.m0ckly.site/m/:publicId/:collection

publicId — идентификатор проекта, он виден на странице проекта. collection — имя коллекции.

Быстрый старт

Первый запрос за минуту

Попробовать без регистрации. Демо-проект открыт для всех, в него можно и писать — просто вставь это в терминал.

попробовать
curl 'https://api.m0ckly.site/m/demo/users/1?_relations=posts'

Данные сбрасываются к исходному сиду каждый час, лимит — 60 запросов в минуту с одного IP, размер записи — до 8 КБ. Всё остальное работает как в обычном проекте: фильтры, сортировка, пагинация, связи и запись. В ответах демо приходит заголовок X-Mockly-Demo.

  1. Создай проект и коллекцию — например products.
  2. Вставь массив объектов JSON. Поле id проставится само.
  3. Дёргай эндпоинт из своего кода.
пример
const res = await fetch('https://api.m0ckly.site/m/demo/products?limit=2')
const products = await res.json()
ответ
{
  "items": [
    { "id": 1, "title": "Compact Mechanical Keyboard",
      "price": 89, "category": "keyboards", "inStock": true },
    { "id": 2, "title": "Full Size Mechanical Keyboard",
      "price": 129.5, "category": "keyboards", "inStock": true }
  ],
  "meta": { "total_items": 40, "total_pages": 20, "current_page": 1, "per_page": 2 }
}
Проекты и коллекции

Как всё устроено

В аккаунте лежат проекты, в проекте — коллекции, в коллекции — записи. При регистрации проект с именем default создаётся сам, так что работать можно сразу.

publicId
https://api.m0ckly.site/m/4f8c1e0a9b3d7c25/products

У каждого проекта свой publicId — 16 hex-символов, выдаются при создании и видны на странице проекта. Только он и определяет проект в адресе мока; переименование проекта его не меняет.

Имена проектов и коллекций — от 1 до 64 символов. Имя уникально в своей области: два проекта в одном аккаунте не могут называться одинаково, как и две коллекции внутри одного проекта.

Удаление проекта уносит его коллекции вместе со всеми записями, удаление коллекции — её записи. Отменить нельзя. Если нужно просто убрать проект из доступа, не теряя данные, — выключи его.

Список коллекций

Что вообще есть в проекте

Корень проекта отдаёт список коллекций и признак, включена ли каждая. Удобно, когда клиент выясняет схему сам, а не знает её заранее.

пример
GET /m/demo

{ "collections": [
  { "name": "comments", "enabled": true },
  { "name": "posts", "enabled": true },
  { "name": "products", "enabled": true },
  { "name": "todos", "enabled": true },
  { "name": "users", "enabled": true }
] }

Выключенные коллекции тоже попадают в список — с enabled: false, при этом на запросы к ним приходит 403. Выключенный проект отдаёт 403 и здесь.

CRUD

Операции над записями

Полный набор методов над коллекцией. Тело запроса и ответа — JSON.

методпутьчто делает
GET/:collectionСписок записей
GET/:collection/:idОдна запись
POST/:collectionСоздать запись
PUT/:collection/:idЗаменить запись целиком
PATCH/:collection/:idОбновить отдельные поля
DELETE/:collection/:idУдалить запись

id генерируется сервером. Если передать его в теле POST — значение игнорируется. PUT заменяет данные полностью, PATCH дописывает переданные поля к существующим.

Параметры запроса

Фильтры, поиск и сортировка

Работают на list-эндпоинте и комбинируются в любом порядке.

параметрчто делает
?title=MouseЧисловое значение сравнивается точно; любое другое — совпадение по подстроке без учёта регистра
?title=Portable*Явный шаблон без учёта регистра: * — любой набор символов, шаблон привязан к обоим концам (для подстроки пиши *mouse*)
?price_gte=20&price_lte=90Числовой диапазон, ≥ и ≤
?q=mouseПоиск подстроки сразу по всем полям записи, без учёта регистра
?sortBy=price&order=descСортировка по полю, order — asc или desc
?page=2&limit=10Постраничная выдача
пример
GET /m/demo/products
  ?sortBy=price&order=asc
  &price_gte=20&page=1&limit=10

Имена page, limit, sortBy, order, q и _relations зарезервированы — как фильтры по одноимённым полям они не сработают. Диапазоны _gte и _lte применяются только к числовым значениям, остальное пропускается.

Обычный ?title=mouse теперь находит любые title, содержащие «mouse», без учёта регистра. Для префикса или суффикса используйте * (?title=*mouse), а числа сравниваются точно (?price=89).

Пагинация

Постраничная выдача

По умолчанию list-эндпоинт отдаёт обычный массив. Передай page или limit — и ответ завернётся в конверт с метаданными. Если limit не передан, размер страницы — 10; передача одного page тоже даёт 10, а не размер страницы, настроенный у коллекции.

ответ
{
  "items": [ … ],
  "meta": {
    "total_items": 50,
    "total_pages": 5,
    "current_page": 1,
    "per_page": 10
  }
}

Чтобы конверт приходил всегда, включи «Пагинацию» в настройках коллекции. Там же задаётся размер страницы по умолчанию и убирается поле total_pages, если оно не нужно.

Связи

Подстановка связанных записей

Параметр _relations подставляет связанный объект прямо в запись. Через запятую можно перечислить несколько связей.

пример
GET /m/demo/posts/1?_relations=user

{ "id": 1, "userId": 1, "title": "Why we moved search back to Postgres",
  "user": { "id": 1, "name": "Ada Whitfield", "city": "Lisbon", … } }

Связь работает по соглашению об именах: _relations=user ищет в записи поле userId и тянет запись из коллекции users. Если коллекции нет или ссылка битая — в поле придёт null.

Тот же параметр работает и в обратную сторону. Укажите имя коллекции как есть — _relations=posts на записи из users — и получите массив всех постов, ссылающихся обратно через userId. У родителя без детей будет пустой массив. Если подходят оба прочтения, выигрывает единственное число.

пример
GET /m/demo/users/1?_relations=posts

{ "id": 1, "name": "Ada Whitfield", "city": "Lisbon",
  "posts": [{ "id": 1, "userId": 1, "title": "Why we moved search back to Postgres", … }, … ] }
Настройки коллекции

Искусственные ответы и отключение

Искусственный ответ заставляет коллекцию отвечать фиксированным статусом и произвольным телом на любой запрос — удобно, чтобы проверить обработку ошибок на фронтенде. Подойдёт любой статус от 100 до 599. Если тело не задано, придёт объект со статусом и его текстовым описанием.

Искусственный ответ подменяет обычный обработчик: он применяется ко всем включённым методам, а фильтры, пагинация и связи не вычисляются вовсе. Проверки доступа срабатывают раньше — выключенный проект или коллекция отдадут 403, приватный ресурс без токена 401, выключенный метод 405. С самими записями ничего не происходит — убери статус, и коллекция снова отвечает как обычно.

Разрешённые методы переключаются на каждой коллекции отдельно: чтение (GET), создание (POST), обновление (PATCH, PUT) и удаление (DELETE). Выключенный метод отвечает 405 Method Not Allowed; панель сохраняет полный доступ.

Задержка ответа держит каждый запрос к коллекции заданное время — до 10 секунд. Помогает проверить скелетоны, спиннеры и таймауты на живом сценарии; применяется ко всем методам, включая искусственный ответ.

Выключенные проект или коллекция отдают 403. Сами данные при этом не теряются — достаточно включить обратно.

Лимиты

Сколько всего можно

Цифры рассчитаны на прототипы и не настраиваются.

лимитзначение
Коллекций в проекте25
Записей в коллекции500
Объектов за один импорт500
Записей в одной массовой операции1000
per_page в настройках коллекции1–100
Имя проекта или коллекции1–64
Запросов в минуту к мокам проекта600

Превышение любого из лимитов отвечает 409 — как и дубль имени проекта или коллекции. Сверх минутного бюджета приходит 429; у /auth и /register свой счёт: 20 попыток за 5 минут с одного адреса.

Коды ответов

Что приходит в ответ

кодкогда
200Успешные GET, PUT или PATCH
201Запись создана через POST
204Запись удалена через DELETE, тело ответа пустое
400Тело запроса — не валидный JSON-объект
401Приватный ресурс без валидного токена · неверные учётные данные или refresh-токен
403Проект выключен в настройках · Коллекция выключена в настройках
404Проект, коллекция или запись не найдены
405Метод выключен в настройках коллекции
409Достигнут лимит либо проект, коллекция или аккаунт с таким именем уже существует
413Запись больше 8 КБ — только в демо-проекте
429Исчерпан минутный бюджет запросов проекта или лимит попыток входа

У ошибок тело вида: { "error": "..." }

Безопасность

Моки открыты всем

По умолчанию у mock-эндпоинтов нет авторизации. Ни токена, ни заголовка, ни проверки источника — CORS открыт для любого сайта. Кто угодно со ссылкой может читать записи, создавать новые, менять и удалять их.

Поэтому считай содержимое коллекции публичным. Не клади туда реальные персональные данные, ключи, токены и выгрузки из продакшена. publicId не секрет: он едет в адресе и оседает в истории браузера, логах и везде, куда ты его вставишь.

Если ссылка утекла — выключи проект: эндпоинты сразу начнут отдавать 403, а данные останутся на месте. Приватные ресурсы помогают замокать сценарий логина, но это защита мок-уровня: данным за ними стоит доверять не больше, чем остальным.

Документация · mockly