active-mdx
active-mdx copied to clipboard
GraphQL Server
Would it be possible to expose this as a read-only GraphQL server?
I love the idea of keeping all my data in Git, but I'd still like to consume it from other services
Yes it absolutely would. It is something I've been meaning to get around to. I'll give you a brain dump of my current thoughts on it in case you want to try it out.
Here is an example of a plugin Google Sheets Plugin
I would develop this as a plugin
import { Collection } from '@active-mdx/core'
import GraphQlPlugin from '@active-mdx/graphql'
export const collection = new Collection({
rootPath: "./docs"
}).use(GraphQlPlugin, { ...options })
That plugin would define a function on the collection to generate a graphql API.
I think you could generate the entire graphql API without needing custom code, unless you wanted to.
Here is an ActiveMDX project https://github.com/soederpop/active-mdx/tree/main/packages/software-project-demo-site/docs
If you import this module, you are getting an instance of the ActiveMDX Collection
The collection exposes information about the available model classes
import docs from "./docs/index.mjs"
docs.modelClasses // => [Epic, Story, Standup, Decision]
Each model class has a static property inflections, in this example I can go from the Epic and Story model to "epics", "stories". These names could be used to generate query functions.
Each model class also has an availableQueries property, for pre-determined queries you define on your model class. These could be used to generate available graphql queries as well.
Each model class can also, optionally export a joi schema ( for validation purposes. ) I think this can be inspected somehow to generate a graphql type for each of the models.
So I think using this data, you could generate a graphql schema, as well as resolver functions.
// resolvers.js
module.exports = {
Query: {
epics: (_, __, { collection }) =>
collection.query('Epic').fetchAll()
}
};
I would have every node / object have common properties like id, model type, meta, title, ast. etc.
Finally, you would just need to wrap it with like apollo-graphql, but in the end you would just be able to say
collection.createGraphqlApi(options)
and get something you could serve with express or whatever.
You can call describe() on a joi schema.
{
"type": "object",
"flags": {
"unknown": true
},
"keys": {
"meta": {
"type": "object",
"flags": {
"presence": "required",
"unknown": true
},
"keys": {
"status": {
"type": "string",
"flags": {
"presence": "required"
},
"rules": [
{
"name": "pattern",
"args": {
"regex": "/^(created|in-progress|qa|approved|complete)$/",
"options": {
"name": "valid statuses"
}
}
}
]
},
"estimates": {
"type": "object",
"flags": {
"unknown": true,
"presence": "required"
},
"keys": {
"high": {
"type": "number",
"flags": {
"presence": "required"
}
},
"low": {
"type": "number",
"flags": {
"presence": "required"
}
}
}
},
"github": {
"type": "object",
"keys": {
"issue": {
"type": "number"
}
}
}
}
}
}
}
You could easily take that object and generate a graphql type.
@rawkode just pushed up a commit. still need to document and test.
If you clone the repo and run yarn
then
$ cd packages/software-project-demo-site
$ node scripts/graphql.mjs
It will start a graphql server you can open on http://localhost:4000
Just a proof of concept of what is possible.
To use it you need @active-mdx/core and @active-mdx/graphql >= 0.9.1
wow