Imagine a database that can validate JSON data using a JSON Schema scheme, process events, and process data. And if the idea is implemented as a service using mongodb ?
We have developed just such a service. He is used by our side projects:
Under the cut a brief description of the main features of the service with examples.
This article contains sections:
All entities in the service are JSON documents. Thanks to that, mongodb was great for us.
You can work with documents through HTTP REST Api, CLI and Python clients.
I prefer CLI.
Here are some examples of its use:
venues
collection deform document create -c venues -d '{"text":"hello world"}'
$ deform documents count -c my_project_users 108
I will say right away - the choice fell on JSON Schema draft v4. This scheme provides a lot of useful.
Let's say that 2 documents come to you:
{ "name": " 1 ", "price": 1.0, "currency": "RUB" }
{ "name": "1$ stuff", "price": 1.99, "currency": "United States Dollar" }
And we need the second document to fail to go to the database - the currency has been transferred incorrectly ( currency
property).
Let's create a scheme by which the first document passes, and the second one does not.
{ "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"] }
Pay attention to the currency
and its enum
property. Only documents whose currency coincides with the lines "RUB", "USD", "CAD", "GBP" will be considered correct.
Deform supports working with files. All your files will be documents in the _files
collection. And in the document itself, where you attached the file, it will also be available as an object.
Let's add to the scheme with the goods a new property - the image of the goods.
{ "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"] }
Now we can upload a picture to this product.
Using the CLI, create a document:
$ deform document create -c goods -d '{ "name": "Teapot", "price": 11.99, "currency": "GBP", "image": @"/tmp/teapot.png" }'
As a result, we get
{ "_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 } }
You can get the contents of the file both from the collection with the files and from the product document itself.
Link to the documentation section with files
Deform can process data. Full list of handlers .
Suppose that we need to change the size of the product image at the time of its creation.
This will help us resize
processor (at the moment it works with images only)
The scheme will turn into:
{ "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] } } } ] } } }
Link to the documentation section with processing
Our webhukas write history and they have events. They also have headers, methods, and their own validation of matched documents.
Suppose that we need a notification in slack that the product was created. The hook will look like this:
{ "name": "Slack notification", "url": "https://hooks.slack.com/services/....", "method": "POST", "triggers": ["created"], "collection": "slack_notifications" }
Pay attention to the triggers
property - in this case only the created documents will trigger the hook.
Now suppose that we only need notifications about goods, where the price is more than 1000
and the USD
currency:
{ "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"] } } }
If the document is correct for the scheme inside the condition
- the hook will work.
Link to the documentation section with hooks
This article is a brief overview of the main features of the project.
If you are interested in it, I will give you any feedback, including objective criticism: D
Several links to the project:
Source: https://habr.com/ru/post/305156/
All Articles