{"id":25638357,"url":"https://github.com/miniql/miniql","last_synced_at":"2025-04-15T00:09:21.775Z","repository":{"id":42749605,"uuid":"280339249","full_name":"miniql/miniql","owner":"miniql","description":"A tiny JSON-based query language inspired by GraphQL","archived":false,"fork":false,"pushed_at":"2023-03-05T06:21:44.000Z","size":539,"stargazers_count":125,"open_issues_count":12,"forks_count":7,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-04-15T00:09:04.341Z","etag":null,"topics":["data","data-analysis","data-science","graphql","javascript","json","queries","query","query-language","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/miniql.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","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},"funding":{"github":"ashleydavis"}},"created_at":"2020-07-17T05:55:26.000Z","updated_at":"2024-07-23T09:30:35.000Z","dependencies_parsed_at":"2024-11-27T08:41:17.080Z","dependency_job_id":null,"html_url":"https://github.com/miniql/miniql","commit_stats":{"total_commits":86,"total_committers":1,"mean_commits":86.0,"dds":0.0,"last_synced_commit":"1413cb870c5e1763f4998caecfce2eed76b47a52"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/miniql%2Fminiql","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/miniql%2Fminiql/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/miniql%2Fminiql/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/miniql%2Fminiql/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/miniql","download_url":"https://codeload.github.com/miniql/miniql/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248981268,"owners_count":21193147,"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":["data","data-analysis","data-science","graphql","javascript","json","queries","query","query-language","typescript"],"created_at":"2025-02-23T02:24:57.851Z","updated_at":"2025-04-15T00:09:21.758Z","avatar_url":"https://github.com/miniql.png","language":"TypeScript","funding_links":["https://github.com/sponsors/ashleydavis"],"categories":[],"sub_categories":[],"readme":"# MiniQL\n\nA tiny JSON-based query language inspired by GraphQL\n\nPronounced \"miniquel\", similar to \"miniscule\".\n\nNew to this? Check out the examples below or jump to [getting started](#getting-started).\n\nFor a quick idea of what queries look like and how they work, jump straight into [the interactive example](https://miniql.github.io/miniql-interactive-example/).\n\n[Click here to support my work](https://www.codecapers.com.au/about#support-my-work)\n\nLove this? Please star this repo!\n\n# MiniQL in a nutshell\n\n![Diagram of MiniQL](./images/miniql.png)\n\n# Examples\n\n## Interactive example\n\nThere's an interactive browser-only example of MiniQL here:\n\nhttps://miniql.github.io/miniql-interactive-example/\n\nYou fnd find the code for it here:\n\nhttps://github.com/miniql/miniql-interactive-example\n    \n## Node.js + CSV files\n\nHere is an example of making MiniQL queries against a CSV file dataset under Node.js:\n\nhttps://github.com/miniql/miniql-csv-example\n\n## Node.js + JSON files\n\nHere is an example of making MiniQL queries against a JSON file dataset under Node.js:\n\nhttps://github.com/miniql/miniql-json-example\n\n\n## JavaScript notebook\n\nHere is an easy to read MiniQL example in a JavaScript notebook\n\nhttps://miniql.github.io/notebook-example/\n\n## Frontend + Express REST API + MongoDB\n\nHere is an example of using MiniQL to make queries against a MongoDB database through an Express REST API to display query results in the frontend.\n\nhttps://github.com/miniql/miniql-express-mongodb-example\n\n# Motivation\n\nGraphQL is awesome, but sometimes the following can be annoying...\n\n- It is big and complicated.\n- It introduces a new language into your stack.\n- I don't want to define a \"schema\". \n    - Schemaless is the best way to prototype an MVP when you don't know what the data is yet.\n- It's tedious to have to specify everything you want returned.\n    - Sometimes you just want everything returned! Especially when you are exploring your data!\n\n# Aims\n\n- To be tiny, yet flexible.\n- To easily create queries.\n- To easily implement the backend.\n- To have a single query end point where auth can be implemented.\n- To avoid having many separate REST APIs.\n- To be able to retreive aggregate and optimized data to the front end.\n- To be able to easily explore data.\n- To not impose unecessary structure or rules on your data!\n- Make the most of the backend capabilities (eg search and filtering capability in the database)\n\n# Features\n\n- The query language is JSON and can easily be sent over the weire.\n- The results are JSON and can easiy be received over the wire.\n- MiniQL works in both Node.js and the browser.\n    - MiniQL can potentially work in other programming languages, if someone wants to create an implementation for their own fav language.\n- Decouples the query engine from entity resolution ([separation of concerns](https://\n- There is no enforced schema, just like MongoDB. \n    - But you can easily make your own [JSON schema](https://json-schema.org/) for validation and intellisense in the frontend.\nen.wikipedia.org/wiki/Separation_of_concerns)).\n- There is no built-in type system - use your programming language for that! (e.g. TypeScript)\n- Follows relationships and resolves nested entities.\n    - You control how the relationships in your data are defined.\n- Aggregates query results from different data sources.\n- Supports arbitrary user-defined types of operations:\n    - The MiniQL convertion is have \"get\" or \"update\" operations.\n    - But use whatever names you like.\n    - You can have any other operations as well with whatever names you like.\n- Optionally alias entities in the output. You control the field names that returned in the query result.\n- The \"query\" is passed through to the resolver, you can build your own resolver or use one of the existing plugins:\n    - [JSON files](https://www.npmjs.com/package/@miniql/json)\n    - [CSV files](https://www.npmjs.com/package/@miniql/csv)\n    - [Inline data](https://www.npmjs.com/package/@miniql/inline)\n\n# Bring your own\n\nMiniQL delegates queries for entities to the *query resolver*.\n\nThe query resolver is something that you implmenent or is provided by a MiniQL plugin (such as the [JSON plugin](https://www.npmjs.com/package/@miniql/json), the [CSV plugin](https://www.npmjs.com/package/@miniql/csv) or the [Inline data plugin](https://www.npmjs.com/package/@miniql/inline)).\n\nImplementing your own resolver means you can have what ever features you like in the backend.\n\nAdding features like these is completely under your control:\n\n- Pagination\n- Retrieving total entities\n- Entity search and filtering\n- Included fields\n- Excluded fields\n- Or anthing else you can think of!\n\nYou can manage how data is returned, e.g:\n\n- Blacklisted fields\n- Whitelisted fields\n- All data, partial data, whatever you want!\n\n# Future\n\n- Add a configurable MongoDB resolver.\n- Caching and aggregation (wishlist)\n- Hooks - be notifed when particular entities/fields have been updated.\n- Optimisation to do queries in parallel.\n- Built-in filtering?\n- How to retreieve a count after search/filtering is applied.\n\n# Getting started\n\nInstall MiniQL:\n\n```bash\nnpm install --save miniql\n```\n\nImport MiniQL (JavaScript):\n\n\n```javascript\nconst { miniql } = require(\"miniql\");\n```\n\nImport MiniQL (TypeScript):\n\n```typescript\nimport { miniql } from \"miniql\";\n```\n\nNow we must create a query resolver. For this example we'll use a `character` entity (see the Star Wars data in [the interactive example](https://miniql.github.io/miniql-interactive-example/)).\n\nWe need to define functions for retrieving and updating our character entity:\n\n```javascript\nconst queryResolver = {\n    get: {\n        character: {\n            invoke: async (args: any, context: any) =\u003e { // Handles a 'get' query.\n                if (args.name !== undefined) {\n                    // Asking for a particular named character.\n                    // Look up the single named character in your database and return it.\n                    const theCharacter = ...;\n                    return theCharacter;\n                }\n                else {\n                    // Asking for all characters.\n                    // Look up all characters in your database and return them.\n                    const allCharacters = ...;\n                    return allCharacters;\n                }\n            }\n        }\n    },\n\n    update: {\n        character: {\n            invoke: async (args: any, context: any) =\u003e { // Handles an 'update' query.\n                if (args.name !== undefined) {\n                    const updateParams = args.params;\n                    // Store `updateParams` against the single \n                    // named character in your database.\n                }\n                else {\n                    const updateParams = args.params;\n                    // Add a new named character with \n                    // `updateParams` in your database.\n                }\n            },\n        },\n    },\n};\n```\n\nThere's various plugins that can create a query resolver for us depending on our data source:\n- [JSON files](https://www.npmjs.com/package/@miniql/json)\n- [CSV files](https://www.npmjs.com/package/@miniql/csv)\n- [Inline data](https://www.npmjs.com/package/@miniql/inline)\n\n\nA MonogDB query resolver is coming soon! If you'd like to implement a resolver for your own favorite database [please let me know](mailto:ashley@codecapers.com.au).\n\nNow that we have a query resolver we can execute queries against it with MiniQL.\n\nFirst we need a query, let's create one to get the character called \"Darth Vader\":\n\n```javascript\nconst getQuery = {\n    get: { // This is a 'get' operation.\n        character: {\n            args: {\n                name: \"Darth Vader\", // We are retrieving the record for Mr Vader.\n            },\n        },\n    },\n};\n```\n\nNow we can execute the `get` query to retreive the record for Mr Vader:\n\n```javascript\nconst context = {}; // Global context passed to our resolver.\nconst queryResult = await miniql(getQuery, queryResolver, {}); // Executes the query.\nconsole.log(queryResult);\n```\n\nHere's the output of the query:\n\n```json\n{\n    \"character\": {\n        \"name\": \"Darth Vader\",\n        \"height\": 202,\n        \"mass\": 136,\n        \"hair_color\": \"none\",\n        \"skin_color\": \"white\",\n        \"eye_color\": \"yellow\",\n        \"birth_year\": \"41.9BBY\",\n        \"gender\": \"male\",\n        \"homeworld\": \"Tatooine\",\n        \"species\": \"Human\"\n    }\n}\n```\n\nNow let's execute an `update` query to modify mr Vader's record:\n\n```javascript\nconst updateQuery = {\n    update: { // This is an 'update' operation.\n        character: {\n            args: {\n                name: \"Darth Vader\",\n                params: {\n                    // Sets Mr Vaders hair color.\n                    hair_color: \"brown\", // At least it was brown back when he had hair.\n                },\n            },\n        },\n    },\n};\n```\n\nNow we execute the `update` query against our query resolver:\n\n```javascript\nconst context = {};\nawait miniql(updateQuery, queryResolver, {});\n```\n\nMr Vader's hair color is now set to \"brown\".\n\nHave fun with MiniQL!\n\nMore advanced documentation is coming soon! [Follow for updates.]((https://twitter.com/codecapers))\n\n# Wishlist\n\n- Parallelise complex queries over multiple nodes.\n\n# Support the developer \n\n\u003ca target=\"_blank\" href=\"https://www.codecapers.com.au/about#support-my-work\"\u003eSee the ways you can **support the developer.**\u003c/a\u003e","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fminiql%2Fminiql","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fminiql%2Fminiql","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fminiql%2Fminiql/lists"}