Что такое 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.
- Создай проект и коллекцию — например products.
- Вставь массив объектов JSON. Поле id проставится само.
- Дёргай эндпоинт из своего кода.
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 создаётся сам, так что работать можно сразу.
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 и здесь.
Операции над записями
Полный набор методов над коллекцией. Тело запроса и ответа — JSON.
id генерируется сервером. Если передать его в теле POST — значение игнорируется. PUT заменяет данные полностью, PATCH дописывает переданные поля к существующим.
Фильтры, поиск и сортировка
Работают на list-эндпоинте и комбинируются в любом порядке.
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. Сами данные при этом не теряются — достаточно включить обратно.
Сколько всего можно
Цифры рассчитаны на прототипы и не настраиваются.
Превышение любого из лимитов отвечает 409 — как и дубль имени проекта или коллекции. Сверх минутного бюджета приходит 429; у /auth и /register свой счёт: 20 попыток за 5 минут с одного адреса.
Что приходит в ответ
У ошибок тело вида: { "error": "..." }
Моки открыты всем
По умолчанию у mock-эндпоинтов нет авторизации. Ни токена, ни заголовка, ни проверки источника — CORS открыт для любого сайта. Кто угодно со ссылкой может читать записи, создавать новые, менять и удалять их.
Поэтому считай содержимое коллекции публичным. Не клади туда реальные персональные данные, ключи, токены и выгрузки из продакшена. publicId не секрет: он едет в адресе и оседает в истории браузера, логах и везде, куда ты его вставишь.
Если ссылка утекла — выключи проект: эндпоинты сразу начнут отдавать 403, а данные останутся на месте. Приватные ресурсы помогают замокать сценарий логина, но это защита мок-уровня: данным за ними стоит доверять не больше, чем остальным.