{"id":15062646,"url":"https://github.com/wesovilabs/mollydb","last_synced_at":"2025-08-25T07:08:26.350Z","repository":{"id":70939495,"uuid":"126442462","full_name":"wesovilabs/mollydb","owner":"wesovilabs","description":"A GraphQL configuration file database","archived":false,"fork":false,"pushed_at":"2018-12-18T03:17:31.000Z","size":10882,"stargazers_count":8,"open_issues_count":4,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-24T09:02:51.456Z","etag":null,"topics":["configuration","database","go","golang","graphql","graphql-api","hooks","storage","yml"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/wesovilabs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","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":"2018-03-23T06:26:28.000Z","updated_at":"2021-06-04T16:00:47.000Z","dependencies_parsed_at":null,"dependency_job_id":"f6ae464d-e3d0-4fa5-a63d-9e2153faf03b","html_url":"https://github.com/wesovilabs/mollydb","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wesovilabs%2Fmollydb","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wesovilabs%2Fmollydb/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wesovilabs%2Fmollydb/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wesovilabs%2Fmollydb/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/wesovilabs","download_url":"https://codeload.github.com/wesovilabs/mollydb/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248198884,"owners_count":21063628,"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":["configuration","database","go","golang","graphql","graphql-api","hooks","storage","yml"],"created_at":"2024-09-24T23:44:04.926Z","updated_at":"2025-04-10T10:08:51.444Z","avatar_url":"https://github.com/wesovilabs.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"    docker run -it \\\n        -p 9090:9090 \\\n        -v /tmp/data/mollydb:/var/mollydb/data \\\n        wesovilabs/mollydb:0.0.1-alpha\n\n# Project Status\nmollydb is not stable at all, the API  is in continuous definition and some \narchitecture topics are not closed.\n\nLearning from provided feedback to toward the project correctly.\n\n# About\n\nMollyDB is a **configuration file database** that provides a **GraphQL** API.\n\nIt permits interacting with configuration files like If they were \ntables in a relational database system or documents in a document based \ndatabase.\n\n# Architecture overview\n\n## MollyDB Hierarchy\n\nMollyDB works in a distributed way and it's able to deal with storage that are \nhosted on different paths.\n\nHierarchy in mollydb is defined as:\n\n### Storage\nA storage can be defined as a place where documents are hosted. \nSo far, only local directories are supported but in the near future other \nplaces such as **ssh directory**, **database collections** or even git \nrepository could be understand as **a storage**\n \nSample of storage would be: \n- file:/var/data/databases \n- file:/var/data/micro-services\n \n \n### Documents\nAs is said in the storage paragraph description, a storage contains documents.\nSo far, **only files with yml extension are supported**. \n\nFor example, the storage database, in path *file:/var/data/databases*  \ncontains the files: *mongodb.yml*, *mysql.yml* and ListOfDocuments.docs, but \nonly the following will be understood as document.  \n- mongodb.yml  \n- mysql.yml\n\n\n### Property\nA property is defined as any configurable value in a document\nFor example, a document api-gateway.yml whose content is:\n   \n   ```yaml\n   self:\n     port: 7000\n     address: 0.0.0.0\n   log:\n     level: DEBUG\n   services:\n     accounts:\n       address: localhost:7001\n   ```\n \n provides the following properties:\n - self.port\n - self.addres\n - log.level\n - services.accounts.address \n\n\n### Scenario\n\nA clearer scenario is showed below\n\n\n![mollydb](https://github.com/wesovilabs/mollydb/wiki/assets/architecture-overview.png)\n\n\n## Registering a storage\n\nOnce mollydb is up and running we must proceed to **register a storage** in the\n system. We can do it by making use of the provided **GraphQL API**.\n \n```bash\ncurl -XPOST http://localhost:9090/graphql \\\n  -H 'Content-Type: application/graphql' \\\n  -d 'mutation registerI18nDirectory { register\n  (path:\"resources/data/databases\",  \n        name:\"db\"){ name len documents { name } } }'\n```\n\nOnce the storage is registered in mollydb, a daemon will be launch \nand it will monitor documents in the storage. In case of a new documentis \ncreated mollydb will be updated. The same occurs when a file is deleted \nor a file is modified. \n\n## Creating a hook\n\nMollydb provide you a way yo avoid being making connections every now and \nthen if you need to be informed whena  property is changed.\n\nTo do this we can make use of the **hooks**. So far, only Rest hooks are \nsupported. Yo will create a hook by setting the **property path** you want\n to listen and the url and verb that will be invoked when the property changed.\n\n**RestHook** \n \n```bash\ncurl -XPOST http://localhost:9090/graphql \\\n  -H 'Content-Type: application/graphql' \\\n  -d 'mutation { addRestHook (uri: \n  \"http://localhost:3000/properties/mongodb-port\", verb: \"PUT\", path: \n  \"mollydb://db/mongodb?key=database.port\") }' \n```\n\n*What does the above code means?*\n\nWhen the poperty database.port in document mongodb (that belongs to the \nregistered storage db) changes, then mollydb will make the next request **PUT \nhttp://localhost:3000/properties/mongodb-port** with the \nbelow body\n\n```json\n{\n    \"path\": \"mollydb://db/mongodb?key=database.port\",\n    \"key\": \"database.port\",\n    \"value\": 27030 \n}\n```\n\n# Running mollyDB\n\n## Download executables\n\n- [Mac executable](https://github.com/wesovilabs/mollydb/releases/download/0.0.1-alpha/mollydb.darwin)\n- [Windows executable](https://github.com/wesovilabs/mollydb/releases/download/0.0.1-alpha/mollydb.exe)\n- [Linux executable](https://github.com/wesovilabs/mollydb/releases/download/0.0.1-alpha/mollydb.linux)\n\n## From the code\n\n- Clone the repository into your local machine: \n\n```shell\n    git clone https://github.com/wesovilabs/mollydb.git\n```\n    \n- Checkout the chosen tag.\n\n```shell\n    git checkout \u003cmollydb.tag\u003e\n```\n    \n- Run the following command: \n\n```shell    \n    make run \n```\n\n## Docker\n\nDocker images are published as far as a new tag on master branch are created. \n\nBy default mollydb is launched on **port 9090**, so in case of you want to \nforwarding to a different one you will need to indicate it when running \ndocker command\n    \nIn order to being able to make use of local directories as storage in the \ncontainer you will need to mount a volume when running  docker.\n \n**Scenario**: For the below sample we assume you have the path \n**/tmp/data/mollydb* on your local machine and no processes running\n on port 9090\n \n \n```bash \n     docker run -it -p 9090:9090 \\\n     -v /tmp/data/mollydb:/var/mollydb/data wesovilabs/mollydb:0.0.1-alpha\n```\n\n# GraphQL\n\nMollyDB provides a GraphQL API that can be consumed easily\n\n## Types\n\nTypes managed by GraphQL API are the below\n\n### Storage\nA mollyDB storage.\n\n*Fields*\n- **documents**: The list of documents that belong to this storage\n- **len**: The number of documents in the storage\n- **name**: The name of a storage\n\n### Document\nA mollyDB document.\n\n*Fields*\n- **name**: The name of the document. \n- **len**: The number of properties in the document.\n- **properties**: List of properties of the document\n\n### Property\nDocument content\n\n*Fields*:\n- **key**: The key of the property\n- **path**: The path of the property\n- **value**: The value of the property\n\n## Queries\n\n**storageList(name: String = \"any\"): [Storage]** \n\nThis query allow us to deep  from the root of the mollyDB system until a \nProperty definition.\n\n*Sample*\n\n**request**\n```graphql\nquery StorageQuery {\n  storageList { # optional filter name\n    name\n    len\n\tdocuments(name: \"mongodb\") { # optional filter name\n      name\n      len\n      properties { # optional filter key\n        key\n        value\n        path\n      }\n    }\n  }\n}\n```\n**response**\n```json\n{\n  \"data\": {\n    \"storageList\": [\n      {\n        \"documents\": [],\n        \"len\": 6,\n        \"name\": \"i18n\"\n      },\n      {\n        \"documents\": [\n          {\n            \"len\": 4,\n            \"name\": \"mongodb\",\n            \"properties\": [\n              {\n                \"key\": \"database.hostname\",\n                \"path\": \"mollydb://db/mongodb?key=database.hostname\",\n                \"value\": \"mongodb.wesovilabs.com\"\n              },\n              {\n                \"key\": \"database.port\",\n                \"path\": \"mollydb://db/mongodb?key=database.port\",\n                \"value\": \"27030\"\n              },\n              {\n                \"key\": \"database.credentials.username\",\n                \"path\": \"mollydb://db/mongodb?key=database.credentials.username\",\n                \"value\": \"root\"\n              },\n              {\n                \"key\": \"database.credentials.password\",\n                \"path\": \"mollydb://db/mongodb?key=database.credentials.password\",\n                \"value\": \"secret\"\n              }\n            ]\n          }\n        ],\n        \"len\": 3,\n        \"name\": \"db\"\n      },\n      {\n        \"documents\": [],\n        \"len\": 3,\n        \"name\": \"ms\"\n      }\n    ]\n  }\n}\n```\n\n**properties(storage:String = \"any\" document:String = \"any\" property:String =\n \"any\"): [Property]** \n\nFind properties by filtering records by the name of the  storage or/and the \nname of the document or/and the key of the property. Default value for \nfilters is any. The output is an array of type Property\n\n*Sample*\n\n**request**\n```graphql\nquery FindProperties {\n  properties(storage: \"ms\", property: \"log.level\") {\n    path\n    key\n    value\n  }\n}\n```\n\n**response**\n\n```json\n{\n  \"data\": {\n    \"properties\": [\n      {\n        \"key\": \"log.level\",\n        \"path\": \"mollydb://ms/api-gateway?key=log.level\",\n        \"value\": \"${mollydb://ms/global?key=log.level}:DEBUG\"\n      },\n      {\n        \"key\": \"log.level\",\n        \"path\": \"mollydb://ms/global?key=log.level\",\n        \"value\": \"DEBUG\"\n      },\n      {\n        \"key\": \"log.level\",\n        \"path\": \"mollydb://ms/ms-account?key=log.level\",\n        \"value\": \"DEBUG\"\n      }\n    ]\n  }\n}\n```\n\n\n\n**property(path: String): Property** Find a property in any document of any \nstorage by the connection path.  This is an unique value for each property in\n all the mollydb system. The output is a single Property\n\n*Sample*\n\n**request**\n\n```graphql\nquery PropertyPath {\n  property(path: \"mollydb://db/mongodb?key=database.hostname\") {\n    path\n    key\n    value\n  }\n}\n```\n\n**response**\n```json\n{\n  \"data\": {\n    \"property\": {\n      \"key\": \"database.hostname\",\n      \"path\": \"mollydb://db/mongodb?key=database.hostname\",\n      \"value\": \"mongodb.wesovilabs.com\"\n    }\n  }\n}\n```\n\n## Mutations\n\n**register(name: String!path: String!): Storage**\n\nThe purpose of this mutation is registering a new storage into mollyDB\n\n*Sample*\n\n**request**\n```graphql\nmutation registerI18nDirectory {\n  register(path: \"resources/data/i18n\", name: \"i18n\") {\n    name\n  }\n}\n```\n\n**response**\n```json\n{\n  \"data\": {\n    \"register\": {\n      \"name\": \"i18n\"\n    }\n  }\n}\n```\n\n**unRegister(name: String!): String**\n\nThe purpose of this mutation is unregister an existing storage from mollyDB\n\n*Sample*\n\n**request**\n```graphql\nmutation unRegisterI18nDirectory {\n  unRegister(name: \"i18n\")\n}\n```\n\n**response**\n```json\n{\n  \"data\": {\n    \"unRegister\": \"storage deleted successfully!\"\n  }\n}\n```\n\n**propertyRestHook(uri: String! verb: String! path: String!): String**\n\nThe purpose of this mutation is hook property and be notified when these have\n changed\n\n*Sample*\n\n**request**\n```graphql\nmutation AddHook {\n  propertyRestHook(\n    uri: \"http://localhost:3000/properties/mongodb-port\", \n    verb: \"PUT\", \n    path: \"mollydb://db/mongodb?key=database.port\"\n  )\n}\n```\n\n**response**\n```json\n{\n  \"data\": {\n    \"propertyRestHook\": \"property hooked\"\n  }\n}\n```\n\n# Playing with GraphQL\n\n**GraphiQL** is interated with MollyDB \n\nOnce the system si launched you can deal with MollyDB by making use of \nGraphiQL. GraphiQL is deployed in the same port that mollydb. So assuming you\n use the default port 9090, once you have launched molly you can open \n the browser and play with [GraphiQL](http://localhost:9090/)\n \n \n ![graphiql](https://github.com/wesovilabs/mollydb/wiki/assets/graphiql.png)\n \n Below some examples of graphql queries and mutations used to test manually \n the system:\n \n```graphql\n\nmutation registerI18nDirectory {\n  register(path: \"resources/data/i18n\", name: \"i18n\") {\n    name\n  }\n}\n\nmutation unRegisterI18nDirectory {\n  unRegister(name: \"i18n\")\n}\n\nmutation registerDatabaseDirectory {\n  register(path: \"resources/data/databases\", name: \"db\") {\n    name\n  }\n}\n\nmutation registerMicroservicesDirectory {\n  register(path: \"resources/data/microservices\", name: \"ms\") {\n    name\n  }\n}\n\nquery StorageQuery {\n  storagesList {\n    name\n    len\n\t\tdocuments(name:\"mongodb\"){ \n      name\n      len\n      properties {\n        key\n        value\n        path\n      }\n    }\n  }\n}\n\nquery FindProperties {\n  properties(storage: \"ms\", property: \"log.level\") {\n    path\n    key\n    value\n  }\n}\n\nquery PropertyPath {\n  property(path: \"mollydb://db/mongodb?key=database.hostname\") {\n    path\n    key\n    value\n  }\n}\n\nmutation HookQuery {\n  propertyRestHook(uri: \"http://localhost:3000/properties/mongodb-port\", verb: \"PUT\", path: \"mollydb://db/mongodb?key=database.port\")\n}\n\n``` \n\n\n## Links\n\nMollyDB documentation can be found on **Wiki**:\n\n\n## Other Links\n\n[Architecture overview](https://github.com/wesovilabs/mollydb/wiki/Architecture-overview)\n\n[Running mollydb](https://github.com/wesovilabs/mollydb/wiki/Running-mollydb)\n\n[GraphQL](https://github.com/wesovilabs/mollydb/wiki/GraphQL)\n\n[Playing with graphql](https://github.com/wesovilabs/mollydb/wiki/Playing-with-graphql)\n\n[Changelog](https://github.com/wesovilabs/mollydb/wiki/CHANGELOG)\n\n[The road map](https://github.com/wesovilabs/mollydb/wiki/The-road-map)\n\n[Contributing](https://github.com/wesovilabs/mollydb/wiki/Contributing)\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwesovilabs%2Fmollydb","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwesovilabs%2Fmollydb","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwesovilabs%2Fmollydb/lists"}