Прототип GraphQL, MongoDB - без схемы? - PullRequest
0 голосов
/ 04 сентября 2018

Я ищу прототип для приложения с большими объемами данных. У меня есть опыт работы с SQL, но я в настоящее время влюблен в MongoDB из-за отсутствия схемы, которая для прототипа была бы идеальной, потому что она позволяет мне расширять схему во время разработки, пока все не будет правильно. И мне нравится GraphQL по многим причинам, одна из которых заключается в том, что я могу проводить множество тестов и экспериментов прямо на API без создания простого пользовательского интерфейса.

Однако, как я понимаю, GraphQL требует строгого определения схемы. Это означает, что он не работает с MongoDB, по крайней мере, при сохранении атрибута без схемы.

Абсолютным требованием является способность иметь возможности бэк-обработки. Мне нужно иметь возможность инициировать вычисления данных, поэтому мне нужен какой-то способ написания кода для базы данных, в идеале в той же среде, которая используется для API (конечно, я всегда мог написать какое-то произвольное приложение, ориентированное на БД, но почему я должен использовать две рамки?)

Это правильно или я ошибаюсь? Существует ли эквивалент Graphile для MongoDB, который позволяет мне определять мою схему (которая будет часто меняться при создании прототипов) только в одном месте и обновлять все на лету? Или я вообще иду по неверному пути?

Примечания:

  • Это не рабочий код. Это прототип кода и требует много итераций с различными заинтересованными сторонами, чтобы получить право. Вот почему мне нужно что-то, что позволяет быстро разрабатывать и вносить изменения, если это возможно, прямо здесь и сейчас, чтобы быстро проверить альтернативный подход.
  • Мне нужен какой-то интерфейс, который не-кодер может хотя бы понять. Язык запросов GraphQL достаточно хорош для этой цели (заинтересованные лица - технические люди, но не программисты). Чистый SQL сомнителен, все, что находится за его пределами, слишком много для кодирования.
  • Меня не волнует SQL, NoSQL или даже Graph DB, и меня тоже не волнует, написано ли это на PHP, Java, NodeJS или что-то еще, что я могу понять и взломать (т. Е. Не в Brainfuck).

1 Ответ

0 голосов
/ 11 августа 2019
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

UPDATE

Я в конечном итоге пошел с очень упрощенной реализацией с нуля. Делимся в надежде, что другие могут получить бесплатное вдохновение:

https://gist.github.com/ancmikesmullin/526b64b262561fb4ca1be824c2faec7f#file-test-sgql-alpha2-js-L63-L67

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...