Deform: simple database as a service

в 14:15, , рубрики: dbaas JSON mongodb jsonschema, mongodb, Программирование, Разработка под android, разработка под iOS, метки:

Представьте себе базу данных, способную валидировать 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

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

Автор: andrey665

Источник

Поделиться новостью

* - обязательные к заполнению поля