{"id":15138488,"url":"https://github.com/nabildridi/jsonstorewithvertx","last_synced_at":"2026-01-19T13:32:23.049Z","repository":{"id":91856559,"uuid":"492059456","full_name":"nabildridi/JsonStoreWithVertx","owner":"nabildridi","description":"A basic Json documents store built with Vertx, you can perform all kind of CRUD operations on the Json documents with http requests.","archived":false,"fork":false,"pushed_at":"2022-06-03T10:35:40.000Z","size":150,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-06T09:18:41.588Z","etag":null,"topics":["caffeine","flattened-json","java","json","jsonpath","rxjava3","sparkey","vertx"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nabildridi.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-05-13T22:49:39.000Z","updated_at":"2023-09-06T15:10:39.000Z","dependencies_parsed_at":null,"dependency_job_id":"cb4d0734-3c5b-4cee-9e8b-138ce79355d1","html_url":"https://github.com/nabildridi/JsonStoreWithVertx","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nabildridi%2FJsonStoreWithVertx","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nabildridi%2FJsonStoreWithVertx/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nabildridi%2FJsonStoreWithVertx/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nabildridi%2FJsonStoreWithVertx/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nabildridi","download_url":"https://codeload.github.com/nabildridi/JsonStoreWithVertx/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247457815,"owners_count":20941912,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["caffeine","flattened-json","java","json","jsonpath","rxjava3","sparkey","vertx"],"created_at":"2024-09-26T07:40:19.481Z","updated_at":"2026-01-19T13:32:23.020Z","avatar_url":"https://github.com/nabildridi.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# A Json Store with Vertx\r\n\r\nA basic Json documents store built with Vertx, you can perform all kind of CRUD operations on the Json documents with http requests.\r\n\r\n\r\n# Operations list\r\n\r\nWith http requests, you can :\r\n\r\n - Insert a Json document\r\n - Update the whole document\r\n - Update a **part** of the document (partial update)\r\n - Delete a document\r\n - Request a Json document by id\r\n - Request one or multiple **parts** of a document by id\r\n - The usual query operations :\r\n\t - Page number\r\n\t - page size\r\n\t - Sort field\r\n\t - Sort order\r\n\t - Filter\r\n\t - Send only one or multiple **parts** of the documents \r\n\r\n## Limitations\r\n\r\nThis a very basic json store, it doesn't have the concept of collections or other advanced functionalities.\r\nIt's just a personal project playing with Vertx.\r\n\r\n## Java version\r\n\r\nMust be Java 17\r\n\r\n## Build\r\n\r\nbuild the fatjar with :\r\n\r\n    mvn clean install\r\n\r\nand just execute the jar with :\r\n\r\n    java -jar JsonStoreWithVertx-1.0.jar\r\n\r\n\r\n## Configuration\r\n\r\n### Application configuration :\r\nThe application configuration is **conf/config.json**\r\n\r\n\r\n```json\r\n {\r\n\t\"application_port\" : 8080,\r\n\t\"store_fs_path\" : \"d:\\\\.jsonStore\",\r\n\t\"cache_size\" : 100000,\r\n\t\"cache_preload\" : true\r\n}\r\n```\r\n\r\n - **application_port** : the http port of the application\r\n - **store_fs_path** : the location of folder where the json files wil be stored, if omitted then the files will be saved in **\u003cuser.home\u003e/.jsonStore**\r\n - **cache_size** : the maximum size of the cache\r\n - **cache_preload** : if true the application will preload the json documents into the cache at the startup until the maximun size is reached or there is no more documents to cache, if activated the application startup wil take little time (took 4 seconds to preload 33000 json documents from an ssd during tests) but will gain maximum performance later.\r\n\r\n### Http basic authentication configuration :\r\nEvery request must provide http basic authentication (username and password), the usernames and passwords can be configured in **vertx-users.properties** file.\r\n\r\nThe default username and password are **admin** and **password**\r\n\r\n\r\n# Operations\r\n\r\n## Insert a Json document\r\n\r\n - Path : **/**\r\n - Http method : **POST**\r\n - Header : **Content-Type: application/json**\r\n - **Basic authentication must be present**\r\n - Request body : the json to insert \r\n\r\nThe response will be the provided document with the Id added.\r\n\r\n**Generated id vs provided id** : \r\nthe user can provide a custom id to the document by adding the attribute **_systemId** the Json root of the document before sendinf the request, if omitted then the application will it an auto generated id.\r\n\r\nExample:\r\n**Request body :**\r\n```json\r\n{\r\n\t\"glossary\": {\r\n\t\t\"title\": \"example glossary\"\r\n\t}\r\n}\r\n```\r\n**Response body :**\r\n```json\r\n{\r\n\t\"glossary\": {\r\n\t\t\"title\": \"example glossary\"\r\n\t},\r\n\t\"_systemId\": \"9ECJgNaQWeQIRLy0\"\r\n}\r\n```\r\n\r\n## Update the whole document\r\n\r\n - Path : **/**\r\n - Http method : **POST**\r\n - Header : **Content-Type: application/json**\r\n - **Basic authentication must be present**\r\n - Request body : the json to update\r\n\r\nThe Json sent to the application must contain the original id.\r\n\r\nExample:\r\n**Request body :**\r\n```json\r\n{\r\n\t\"glossary\": {\r\n\t\t\"title\": \"another example\"\r\n\t},\r\n\t\"_systemId\": \"9ECJgNaQWeQIRLy0\"\r\n}\r\n```\r\n**Response body :**\r\n```json\r\n{\r\n\t\"glossary\": {\r\n\t\t\"title\": \"another example\"\r\n\t},\r\n\t\"_systemId\": \"9ECJgNaQWeQIRLy0\"\r\n}\r\n```\r\n## Get a document by id\r\n\r\n - Path : **/{id}?extract=????**\r\n - Http method : **GET**\r\n - **Basic authentication must be present**\r\n\r\nRequest a document by id and optionally with a comma separated list of attributes you want to get instead of the whole document.\r\n\r\n***Example:***\r\n**Request :**\r\n\r\nhttp://localhost:8080/9ECJgNaQWeQIRLy0\r\n\r\n**Response body :**\r\n```json\r\n{\r\n\t\"glossary\": {\r\n\t\t\"title\": \"another example\"\r\n\t},\r\n\t\"_systemId\": \"9ECJgNaQWeQIRLy0\"\r\n}\r\n```\r\n\r\n***Example 2:***\r\n**Whole document :**\r\n```json\r\n{\r\n\t\"glossary\": {\r\n\t\t\"title\": \"example glossary\",\r\n\t\t\"GlossDiv\": {\r\n\t\t\t\"title\": \"S\",\r\n\t\t\t\"GlossList\": {\r\n\t\t\t\t\"GlossEntry\": {\r\n\t\t\t\t\t\"ID\": \"SGML\",\r\n\t\t\t\t\t\"SortAs\": \"SGML\",\r\n\t\t\t\t\t\"GlossTerm\": \"Standard Generalized Markup Language\",\r\n\t\t\t\t\t\"Acronym\": \"SGML\",\r\n\t\t\t\t\t\"Abbrev\": \"ISO 8879:1986\",\r\n\t\t\t\t\t\"GlossDef\": {\r\n\t\t\t\t\t\t\"para\": \"A meta-markup language, used to create markup languages such as DocBook.\",\r\n\t\t\t\t\t\t\"GlossSeeAlso\": [\r\n\t\t\t\t\t\t\t\"GML\",\r\n\t\t\t\t\t\t\t\"XML\"\r\n\t\t\t\t\t\t]\r\n\t\t\t\t\t},\r\n\t\t\t\t\t\"GlossSee\": \"markup\"\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t},\r\n\t\"_systemId\": \"9EE8TAxGnYL7PvbK\"\r\n}\r\n```\r\n\r\n**Request :**\r\n\r\nhttp://localhost:8080/9ECJgNaQWeQIRLy0?extract=glossary.title,glossary.GlossDiv.GlossList.GlossEntry.GlossTerm\r\n\r\n**Response body :**\r\n```json\r\n{\r\n\t\"glossary\": {\r\n\t\t\"title\": \"example glossary\",\r\n\t\t\"GlossDiv\": {\r\n\t\t\t\"GlossList\": {\r\n\t\t\t\t\"GlossEntry\": {\r\n\t\t\t\t\t\"GlossTerm\": \"Standard Generalized Markup Language\"\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t},\r\n\t\"_systemId\": \"9EE8TAxGnYL7PvbK\"\r\n}\r\n```\r\n\r\n\r\n\r\n## Partial update\r\n\r\n - Path : **/**\r\n - Http method : **PUT**\r\n - Header : **Content-Type: application/json**\r\n - **Basic authentication must be present**\r\n - Request body : the fragments that will be inserted and replaced to the main document\r\n\r\nThe response will be the updated main document.\r\n\r\nExample:\r\n**Request body :**\r\n```json\r\n{\r\n\t\"glossary\": {\r\n\t\t\"isbn\": \"978-1-56619-909-4\"\r\n\t},\r\n\t\"GlossDiv\": {\r\n\t\t\"title\": \"S\"\r\n\t},\r\n\t\"_systemId\": \"9ECJgNaQWeQIRLy0\"\r\n}\r\n```\r\n**Response body :**\r\n```json\r\n{\r\n\t\"glossary\": {\r\n\t\t\"isbn\": \"978-1-56619-909-4\",\r\n\t\t\"title\": \"another example\"\r\n\t},\r\n\t\"GlossDiv\": {\r\n\t\t\"title\": \"S\"\r\n\t},\r\n\t\"_systemId\": \"9ECJgNaQWeQIRLy0\"\r\n}\r\n```\r\n\r\n\r\n## Delete\r\n\r\n### Delete by Id\r\n\r\n - Path : **/{id}**\r\n - Http method : **DELETE**\r\n - Header : **Content-Type: application/json**\r\n - **Basic authentication must be present**\r\n - Request body : empty\r\n \r\nThe response will be a json containing the **_systemId** of the deleted document.\r\n\r\n### Delete by request body\r\n\r\n - Path : **/**\r\n - Http method : **DELETE**\r\n - Header : **Content-Type: application/json**\r\n - Request body : Json containing the **_systemId** of the document to delete\r\n\r\nThe response will be a json containing the **_systemId** of the deleted document.\r\n\r\n\r\n# Pagination, sort, filtering and fragments\r\n\r\n - Path : **/query**\r\n - Http method : **POST**\r\n - Header : **Content-Type: application/json**\r\n - **Basic authentication must be present**\r\n - Request body : Json containing the requested pagination, sort, filtering and fragments\r\n\r\nAn example of a full request :\r\n\r\n```json\r\n{\r\n\t\"page\": 0,\r\n\t\"size\": 10,\t\r\n\t\"sortField\": \"glossary.title\",\r\n\t\"sortOrder\": 1,\r\n\t\"filter\": \"$.glossary.GlossDiv[?(@.title =='S' \u0026\u0026 @.GlossList.GlossEntry.ID=='SGML')]\",\r\n\t\"extract\": \"glossary.title , glossary.GlossDiv.GlossList.GlossEntry.ID\"\r\n}\r\n```\r\n\r\n## Pagination\r\n\r\n```json\r\n{\r\n\t\"page\": 0,\r\n\t\"size\": 10\t\r\n}\r\n```\r\n\r\n - **page :** page number, starts with 0 and can't be negative\r\n - **size :**  page size\r\n\r\n## Sorting\r\n\r\n\r\n```json\r\n{\r\n\t\"sortField\": \"glossary.title\",\r\n\t\"sortOrder\": 1\r\n}\r\n```\r\n\r\n - **sortField** : path of the field\r\n - **sortOrder :** 1 for ascending order, -1 for descending\r\n\r\n## Filters\r\n\r\n```json\r\n{\r\n\t\"filter\": \"$.glossary.GlossDiv[?(@.title =='S' \u0026\u0026 @.GlossList.GlossEntry.ID=='SGML')]\"\r\n}\r\n```\r\n\r\n - **Filter :** a  **JsonPath** query  [(github.com/json-path/JsonPath)](https://github.com/json-path/JsonPath)\r\n\r\n## Fragments to extract\r\n\r\n\r\n```json\r\n{\r\n\t\"extract\": \"glossary.title , glossary.GlossDiv.GlossList.GlossEntry.ID\"\r\n}\r\n```\r\n\r\n - **extract** : a comma separated list of the attibutes to be returned in the response, if absent then the whole document will be sent\r\n\r\n\r\n## Some benchmarks :\r\n\r\nTest : 33000 documents fully cached, I7 processor with 16 gb of ram\r\n\r\n|Operation| Time |\r\n|--|--|\r\n| Pagination |  ~7 ms |\r\n| Pagination and sorting | ~45 ms |\r\n| Pagination and extracting  | ~7 ms |\r\n| Pagination, sorting and extracting  | ~40 ms |\r\n| Pagination and filtering  | ~50 ms |\r\n| Pagination, filtering, sorting and extracting | ~35 ms |\r\n\r\n\r\n\r\n\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnabildridi%2Fjsonstorewithvertx","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnabildridi%2Fjsonstorewithvertx","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnabildridi%2Fjsonstorewithvertx/lists"}