[Из песочницы] Deform: simple database as a service

Представьте себе базу данных, способную валидировать JSON данные по схеме JSON Schema, отрабатывать события и обрабатывать данные. А если идея реализованна как сервис, использующий mongodb?


Мы разработали именно такой сервис. Им пользуются наши сайд проекты:


  • docast.me — любые источники данных можно слушать/смотреть в любимом подкастинговом приложении
  • watchlater — решение проблемы watch later youtube
  • warhealth — мобильное приложение

Под катом краткое описание основных особенностей сервиса с примерами.



Эта статья содержит разделы:


  • JSON — JSON документы
  • Validation — валидация данных
  • Files — работа с файлами
  • Processing — процессинг данных
  • WebHook — отработка событий

JSON


Все сущности в сервисе являются JSON документами. Благодаря этому нам отлично подошла mongodb.


Вы можете работать с документами через HTTP REST Api, CLI и Python клиенты.


Я предпочитаю CLI.


Вот несколько примеров его использования:


  • Создать документ в коллекции venues

deform document create -c venues -d '{"text":"hello world"}'

  • Узнать сколько пользователей в проекте

$ deform documents count -c my_project_users
108

Validation


Скажу сразу — выбор пал на JSON Schema draft v4. Эта схема предоставляет много полезного.


Допустим, что к вам приходит 2 документа:


{
    "name": "Товар за 1 руб",
    "price": 1.0,
    "currency": "RUB"   
}

{
    "name": "1$ stuff",
    "price": 1.99,
    "currency": "United States Dollar"
}

И нам нужно, чтобы второй документ не прошел в базу — у него же неправильно передали валюту (свойство currency).


Давайте создадим схему, по которой первый документ пройдет, а второй — нет.


{
    "description": "General goods schema",
    "type": "object",
    "properties": {
        "name": {
            "type": "string"
        },
        "price": {
            "type": "number"
        },
        "currency": {
            "type": "string",
            "enum": ["RUB", "USD", "CAD", "GBP"]
        }
    },
    "required": ["name", "price", "currency"]
}

Обратите внимание на currency и его свойство enum. Лишь документы, у которых валюта совпадает со строками «RUB», «USD», «CAD», «GBP» будут считаться корректными.


Files


Deform поддерживает работу с файлами. Все ваши вайлы будут являться документами в коллекции _files. А в самом документе, куда вы прикрепили файл он также будет доступен в виде объекта.


Давайте добавим в схему с товарами новое свойство — изображение товара.


{
    "description": "General goods schema",
    "type": "object",
    "properties": {
        "name": {
            "type": "string"
        },
        "price": {
            "type": "number"
        },
        "currency": {
            "type": "string",
            "enum": ["RUB", "USD", "CAD", "GBP"]
        },
        "image": {
            "type": "file"
        }
    },
    "required": ["name", "price", "currency"]
}

Теперь мы можем загрузить картинку к этому товару.


Используя CLI, создадим документ:


$ deform document create -c goods -d '{
    "name": "Teapot",
    "price": 11.99,
    "currency": "GBP",
    "image": @"/tmp/teapot.png"
}'

В результате получим


{
    "_id": "576ffce308888f000599ee17",
    "name": "Teapot",
    "price": 11.99,
    "currency": "GBP",
    "image": {
        "_id": "5772db5308888f000599f095",
        "collection_id": "goods",
        "content_type": "image/png",
        "date_created": "2016-06-25T18:31:12.356Z",
        "document_id": "576ec022bd4db46b765ae94a",
        "last_access": "2016-06-25T17:32:18.347Z",
        "md5": "a8eda376612338e0286ff1c1a725b111",
        "name": "teapot.png",
        "size": 16214
    }
}

Получить содержимое файла можно как из коллекции с файлами и из самого документа товара.


Ссылка на раздел документации с файлами


Processing


Deform может обрабатывать данные. Полный список обработчиков.


Допустим, что нам надо изменить размер изображения товара в момент его создания.


В этом нам поможет процессор resize (на данный момент он работает с только изображениями)


Схема превратится в:


{
    "description": "General goods schema",
    "type": "object",
    "properties": {
        "name": {
            "type": "string"
        },
        "price": {
            "type": "number"
        },
        "currency": {
            "type": "string",
            "enum": ["RUB", "USD", "CAD", "GBP"]
        },
        "photo": {
            "type": "file"
        },
        "300x150": {
            "type": "file",
            "processors": [
                {
                    "name": "resize",
                    "in": {
                        "original_image": {
                            "property": "photo"
                        },
                        "size": {
                            "value": [300,150]
                        }
                    }
                }
            ]
        }
    }
}

Ссылка на раздел документации с процессингом


Webhook


Наши вэбхуки пишут историю и у них есть события. Еще у них есть заголовки, методы и своя валидация совпавших документов.


Допустим, что нам нужна нотификация в slack о том, что товар был создан. Хук будет выглядеть так:


{
    "name": "Slack notification",
    "url": "https://hooks.slack.com/services/....",
    "method": "POST",
    "triggers": ["created"],
    "collection": "slack_notifications"
}

Обратите внимание на свойство triggers — в данном случае лишь созданные документы будут вызывать срабатывание хука.


А теперь допустим, что нам нужны уведомления только о товарах, где цена больше 1000 и валюта USD:


{
    "name": "Slack notification",
    "url": "https://hooks.slack.com/services/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",
    "method": "POST",
    "triggers": ["created"],
    "collection": "slack_notifications",
    "condition": {
        "type": "object",
        "additionalProperties": true,
        "price": {
            "type": "number",
            "minimum": 999
        },
        "currency": {
            "type": "string",
            "enum": ["USD"]
        }
    }
}

Если документ будет корректен для схемы внутри condition — хук будет отрабатывать.


Ссылка на раздел документации с хуками


Заключение


Эта статья является небольшим обзором основных возможностей проекта.


Если вам он интересен — буду раз любой обратной связи, включая объективную критику : D


Несколько ссылок по проекту:


  • CLI — CLI для сервиса
  • Python — Python библиотека для использования в своих проектах
  • Документация

Комментарии (0)

© Habrahabr.ru