Создание Javascript объектов только с ключами, чтобы сделать тип безопасным - PullRequest
1 голос
/ 26 марта 2020

Я использую клиент graphql- angular и сервер graphql- ruby и хотел бы создать безопасную систему типов, чтобы другие люди могли писать запросы на стороне клиента и получать ошибки, если запрос, который они написали, не является ' т разрешено. Я не уверен, действительно ли это необходимо, но схема graphql находится на сервере. Таким образом, в моем понимании, если разработчик пишет неверный запрос, клиент отправляет его на сервер, там запрос будет выполнен по схеме, и клиент получит ошибку, верно? Я хотел бы, чтобы клиент не отправлял запрос, если он вызовет ошибку.

Для этого я написал этот класс:

export class RequestQL<request,response> extends Query<response> {
    query:request;
    constructor(apollo,query){
        super(apollo);
        this.query = query;
    }
    document=gql`${convertToString(this.query)}`;
}

Этот класс используется другим классом, который реализует запрос и тип ответа. Например, вот так:

export class ListGrammarDataServiceGQL {
    private _query: RequestQL<ListGraphQlRequest, ListGraphQlResponse>;
    constructor(query:ListGraphQlRequest) {
        this._query = new RequestQL<ListGraphQlRequest, ListGraphQlResponse>(Apollo,query);
    }
    request() {
        return this._query.watch()
            .valueChanges.pipe(
                map(result => result.data)
            );
    }
}

Моя проблема в том, что функция gql получает строку, которая выглядит как объект JavaScript без значений. Поэтому моей первой идеей было создать нормальный объект и добавить случайные значения к ключам, например, например:

{
    list: {
        id: 0,
        name: "",
        slug: ""
    }
}

Затем я попытался написать функцию (convertToString), которая анализирует этот объект в graphql. Строка запроса, но всегда заполнение запроса случайными значениями, которые вам не нужны, это не то, что я ищу. Тип запроса может выглядеть следующим образом:

export interface ListGraphQlRequest {
    list: {
        id
        name
        slug?
        programmingLanguageId
        generatedFromId?
    }
}

Кто-нибудь получил умное решение для этой проблемы? Чего я хочу добиться: - клиент не должен иметь возможность отправлять неверный запрос на сервер. - Разработчики должны напрямую распознавать, если они пишут неверный запрос.

дополнительно: если кого-то интересует функция convertToString (), мы go:

convertToString(obj){
    let str = "";
    Object.keys(obj).forEach( key => {
        if(typeof obj[key] === 'object'){
            str += key;
            str += this.convertToString(obj[key]);
        }
        else {
            str += `${key}\n`
        }
    })
    return `{\n${str}}`;
}
...