Есть ли способ генерировать файлы pb на основе параметров, которые использует метод loadSync?

#node.js #typescript #protocol-buffers #grpc #grpc-node

#node.js #машинописный текст #протокол-буферы #grpc #grpc-узел #typescript

Вопрос:

При использовании динамической генерации кода мы можем загружать .proto файлы с помощью:

 const packageDefinition: PackageDefinition = protoLoader.loadSync(PROTO_PATH, {
  keepCase: true,
  longs: String,
  enums: String,
  defaults: true,
  oneofs: true,
  includeDirs: [__dirname],
});
  

Мы можем установить keepCase опцию сохранения имен полей, не меняя их на верблюжий регистр. И enums опция, поэтому мы можем использовать строковое представление перечислений.

Теперь я использую статическую генерацию кода. Столкнувшись с вышеуказанными двумя проблемами, вот реализация метода моего сервиса:

   public async getTopics(call: ServerUnaryCall<GetTopicsRequest>, callback: sendUnaryData<GetTopicsResponse>) {
    const obj = call.request.toObject();
    const url = `${config.CNODE_API_URL}/topics`;
    const params = {
      page: obj.page || obj.page   1,
      tab: (getEnumKeyByEnumValue(Tab, obj.tab) || '').toLowerCase(),
      mdrender: (getEnumKeyByEnumValue(Mdrender, obj.mdrender) || 'true').toLowerCase(),
      limit: obj.limit,
    };
    try {
      const res = await axios.get(url, { params });
      const data = res.data;
      // console.log(data);
      const topicsResponse = new GetTopicsResponse();
      data.data.forEach((po, i) => {
        const topic = new Topic();
        topic.setId(po.id);
        topic.setAuthorId(po.author_id);
        topic.setTab(Tab[po.tab.toUpperCase() as keyof typeof Tab]);
        topic.setContent(po.content);
        topic.setTitle(po.title);
        topic.setLastReplyAt(po.last_reply_at);
        topic.setGood(po.good);
        topic.setTop(po.top);
        topic.setReplyCount(po.reply_count);
        topic.setVisitCount(po.visit_count);
        topic.setCreateAt(po.create_at);
        const author = new UserBase();
        author.setLoginname(po.author.loginname);
        author.setAvatarUrl(po.avatar_url);
        topic.setAuthor(author);
        topicsResponse.addData(topic, i);
      });
      topicsResponse.setSuccess(data.success);
      callback(null, topicsResponse);
    } catch (error) {
      console.log(error);
      const metadata = new Metadata({ idempotentRequest: true });
      metadata.set('params', JSON.stringify(params));
      metadata.set('url', url);
      const ErrGetTopics: ServiceError = { code: status.INTERNAL, name: 'getTopicsError', message: 'call CNode API failed', metadata };
      callback(ErrGetTopics, null);
    }
  }
  

Вот проблемы, с которыми я сталкиваюсь:

  • Не удается установить значение по умолчанию при использовании proto3, хотите установить для page аргумента значение по умолчанию 1 , А НЕ 0 .
  • Мне нужно преобразовать перечисление из числа в строковое представление вручную.
  • Поля из ответа RESTful API являются регистром snake, но protoc , grpc_tools_node_protoc и grpc_tools_node_protoc_ts плагин генерируют модели, которые имеют поля camel case. Поэтому я хочу сохранить дело.
  • Как вы можете видеть, процесс гидратации неудобен и скучен. Мне нужно вызвать установщиков, чтобы установить значение для поля один за другим.