- PVSM.RU - https://www.pvsm.ru -

Deform: simple database as a service

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

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

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

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

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

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

JSON

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

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

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

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

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

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

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

$ deform documents count -c my_project_users
108

Validation

Скажу сразу — выбор пал на JSON Schema [1] 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
    }
}

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

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

Processing

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

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

В этом нам поможет процессор 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]
                        }
                    }
                }
            ]
        }
    }
}

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

Webhook

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

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

{
    "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 — хук будет отрабатывать.

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

Заключение

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

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

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

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

Автор: andrey665

Источник [20]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/programmirovanie/152226

Ссылки в тексте:

[1] JSON Schema: http://json-schema.org/

[2] mongodb: https://www.mongodb.com/

[3] docast.me: https://docast.me

[4] watchlater: https://watchlater.chib.me

[5] watch later youtube: https://blog.chib.me/whats-wrong-with-youtubes-watch-later-list/

[6] warhealth: https://itunes.apple.com/us/app/war-health/id1077393601?ls=1&mt=8

[7] JSON: #json

[8] Validation: #validation

[9] Files: #files

[10] Processing: #processing

[11] WebHook: #webhook

[12] CLI: https://github.com/deformio/cli-deform

[13] Python: http://deformio.github.io/python-deform/

[14] Ссылка на раздел документации с файлами: http://deformio.github.io/docs/files/

[15] Полный список обработчиков: http://deformio.github.io/docs/processors/

[16] slack: https://slack.com

[17] Ссылка на раздел документации с хуками: http://deformio.github.io/docs/hooks/

[18] CLI: https://github.com/deformio/cli-deform/

[19] Документация: http://deformio.github.io/docs/

[20] Источник: https://habrahabr.ru/post/305156/?utm_source=habrahabr&utm_medium=rss&utm_campaign=sandbox