我正在研究数据繁重的应用程序的原型。我有SQL经验,但是由于缺少模式,我目前对MongoDB颇有好感,这对于原型来说将是理想的,因为它允许我在开发过程中扩展模式,直到一切都正确为止。而且我喜欢GraphQL的原因很多,其中之一就是我可以直接在API上进行很多测试和试验,而无需创建简单的UI。
但是,据我了解,GraphQL需要严格的架构定义。这意味着它不能与MongoDB一起使用,至少在保留无模式属性的情况下不会。
绝对要求是具有后端处理功能的能力。我需要能够触发数据计算,因此我需要某种方式针对数据库编写代码,理想情况下,是在用于API的同一框架中进行(当然,我总是可以编写一些以DB为中心的任意应用程序,但是为什么我应该这样做?使用两个框架?)
是对的还是我被误导了?是否有一个等效的Graphile for MongoDB,它允许我仅在一个地方定义我的架构(在原型开发期间会经常更改),并即时进行所有更新?还是我完全走错了路?
注意:
答案 0 :(得分:0)
const { graphql, buildSchema } = require('graphql');
const schema = buildSchema(`
type Query {
}
type SchemalessDoc {
_id: ID!
json: String!
get(k:String!): SchemalessDoc!
}
type Mutation {
# Authentication
auth(name: String!, phrase: String!): SchemalessDoc!
deauth: Boolean!
# CRUD for all models
create(type:String!, json:String!): SchemalessDoc!
update(type:String!, _id:ID!, json:String!): SchemalessDoc!
delete(type:String!, _id:ID!): SchemalessDoc!
}
`);
// NOTICE: the only difference between Query and Mutation is Parallel vs. Serial execution;
// the labels are more presumptive than prescriptive.
class SchemalessDoc {
constructor(o) {
this.o = o;
}
_id() {
return this.o._id;
}
json() {
// TODO: could return 'null' but that isn't precise. 'undefined' is invalid JSON, but its no biggie,
// just check first: return 'undefined' === s ? undefined : JSON.parse(s);
if (undefined === this.o) return 'undefined';
return JSON.stringify(this.o);
}
get({k}, args, context, info) {
// NOTICE: this would be perfect if an error didn't abort the query
// returning zero results, instead of partial results
// if (undefined === this.o[k]) {
// throw Error(`key ${k} was undefined`);
// }
return new SchemalessDoc(this.o[k]);
}
}
const root = {
// authenticate
auth: function ({ name, phrase }, args, context, info) {
// throw Error(`whats up?`);
return new SchemalessDoc({ _id: 'abcd-efgh-hij', a: { b: { c: 3 }}});
},
deauth(obj, args, context, info) {
debugger;
},
// crud for all models
create(obj, args, context, info) {
debugger;
},
update(obj, args, context, info) {
debugger;
},
delete(obj, args, context, info) {
debugger;
},
};
const query = async s =>
graphql(schema, s, root);
describe('graphql', () => {
it('works', async () => {
const output = await query(`
mutation {
auth(
name: "mike",
phrase: "turkey"
) {
_id,
a: get(k:"a") {
b: get(k:"b") {
x: get(k:"x") {
json
},
c: get(k:"c") {
json
}
}
}
}
}
`);
console.log(JSON.stringify(output)); // =>
// {"data":{"auth":{"_id":"abcd-efgh-hij","a":{"b":{"x":{"json":"undefined"},"c":{"json":"\"hamster\""}}}}}}
debugger;
});
});
// obviously this method requires you to both
// insert data as a JSON string,
// and parse JSON at the very end
// but you can still reduce keys server-side using your get() query
// honestly this is how they should have made it
// and support should be first-class
// no type validation just run it and see
// and stop recursing once you resolve the first null
// and for parallel resolves with some null just return the partial results you have
// and include errors[] for the keys which were undefined
// one downside without that first-class support is
// the json comes back double-escaped as json string inside json.
// the other downside is that it removes the ability to
// do dynamic lookups on foreign key references
// unless you define a specific string or data type for that.
// ie. if it finds a string 'TypeName#abcd-defgh' then it
// could go lookup and attach that document
另请参阅(其他方法):
(我喜欢这一点,因为它提供了类型化的吸气剂,而不是像字符串一样的东西)
http://blog.riand.com/2017/03/schemaless-graphql.html
https://blog.hasura.io/working-with-schemaless-data-with-graphql-on-postgres-574a1ee2e87f/
https://github.com/hasura/graphql-engine/issues/403
更新:
我最终实现了从头开始的极大简化。分享,希望其他人可以从中获得免费的灵感: