向JavaScript自定义中级开发者的目标前进(4)〜kintone REST API Client篇〜

cybozu发表于:2021年03月10日 14:35:47更新于:2021年04月20日 15:43:25

Index

前言

我们曾在向JavaScript自定义中级开发者的目标前进(1) 〜webpack篇〜中介绍了为了自定义多个应用所如何去 使用Webpack。
这次,同样用Webpack环境,来为大家介绍如何安装和使用kintone REST API Client使得处理kintone REST API更为方便。

kintone REST API Client是什么

这是一个通过使用kintone REST API来更简单地操作记录和应用的方便工具。
它能获取全部记录,UPSERT(如已存在现有数据则更新,否则将新建)等。

※本来,有着相同用途的库——kintone JS SDK,但是现在不推荐使用了。
之前如果您一直在使用kintone JS SDK的话,借这次介绍的机会,非常推荐您尝试一下kintone REST API Client。

使用前的准备

就像在向JavaScript自定义中级开发者的目标前进(1) 〜webpack篇〜所说明的一样,让JavaScript处于可编译状态是大前提。

输入下列命令并执行

npm install @kintone/rest-api-client

这样,安装完成后,kintone REST API Client就可以使用了。
如果您是初次使用,可以参考下面文章中的Quick Start章节

kintone JavaScript Client (@kintone/rest-api-client)

使用方法

GitHub的kintone-rest-api-client 中记述了使用方法,因为是英语写成,这里对各个文档的使用方法一一做介绍。

文档

  • 记录的操作

    • 这里记载了获取或创建等相关记录操作。通常来说,这些是最基础的内容。

  • 应用的操作

    • 这里记载了有关更改应用设置的内容。如果是想自动更改应用的设置,可以看这里,但基本上使用频度较低。

  • 文件的操作

    • 这里记载了文件的上传,下载等有关操作的内容。例如将文件添加到记录可参考此处。

  • BulkRequest的操作

    • 这里记载了对多个应用的记录进行批量处理的内容。

文档的阅读方法

文档中有各个项目的函数说明、参数和返回值等说明。英语中不能理解的部分,请用翻译网站等帮助理解。

1. 函数名称
2. 函数说明
3. 函数返回值
4. 函数参数

js-sdk_record_md_at_master___kintone_js-sdk.png

使用示例

下面使用文档中所记载的中一部分作为例子来说明。我们使用async/await的格式来表述。请参考。

获取记录

获取应用ID为1,记录编号为10的记录时做如下操作

const res = await client.record.getRecord({app: "1", id: "10"});

批量获取记录

2020年7月的定期维护中,之后所制作的应用offset的上限为1万件,所以如果想全部获取的话,就有必要使用游标 API

但是,在kintone REST API Client中不必特别在意游标 API的使用,而可以像下面那样一下子获取全部记录。

获取应用ID为1,字段代码为price,price为1000以上的记录时做如下操作

const res = await client.record.getAllRecords({app: "1", condition: "price >= 1000"});

新建记录

应用ID为1, 字段代码为field_code_1里填入"示例文本1"的记录作成时做如下操作

const res = await client.record.addRecord({app: "1", record: {field_code_1: {value: "示例文本1" }}});

更新记录

应用ID为1, 记录ID为10, 字段代码为field_code_1里填入"示例文本2"后更新记录时做如下操作

const res = await client.record.updateRecord({app: "1", id: "10", record: {field_code_1: {value: "示例文本2"}}});

批量更新记录

批量更新下面的三条记录
     应用ID为1, 记录ID为11, 字段代码为field_code_1里填入"示例文本1"
     应用ID为1, 记录ID为12, 字段代码为field_code_2里填入"示例文本2"
     应用ID为1, 记录ID为13, 字段代码为field_code_3里填入"示例文本3"
   时做如下操作

const res = await client.record.updateAllRecords({
  app: 1,
  // 记录由对象数组指定。
  records: [
    {id: '11', record: {field_code_1: {value: '示例文本1'}}},
    {id: '12', record: {field_code_2: {value: '示例文本2'}}},
    {id: '13', record: {field_code_3: {value: '示例文本3'}}},
  ]
});

增补记录

所谓增补,就是指当该记录不存在时新建一条记录,该记录存在时则更新该记录的操作。

应用ID为1, 更新字段代码为"field_key", field_key的值为"apple"的记录, 把字段代码为field_code_1中填入"示例文本1"时做如下操作

const res = await client.record.upsertRecord({
  app: "1", updateKey: {field: "field_key", value: "apple" }, record: {field_code_1: {value: "示例文本1"}}
});

范例

下面展示使用kintone REST API Client来实现应用之间的数据的取用的范例。

方案

准备两个应用。一个是商品列表。另一个是报价单。制作报价单时,用Lookup组件来选取商品列表中的商品。

然后,制作一个符合下列要求的自定义JavaScript。

  1. 制作报价单时(保存记录时),选择商品的数量会使得商品的在库数量减少。

  2. 制作报价单时(保存记录时),选择商品的数量大于在库数量时会报错。

保存时的样子

保存时,所选数量大于在库数不能保存。在库数足够时减去相应数量。

001606e9d66733bc0e12fef7e613c38

应用的准备

1. 下载模板文件

模板文件

2. 创建应用

创建应用时选择"通过导入模板文件创建",选择刚才下载的模板文件来创建。成功后你会发现"商品列表"和"报价单"两个应用已经创建好了。

3. 在商品列表中加入至少一条记录,并填好"在库数量"。

自定义JavaScript

写完代码,把编译好的代码上传到报价单应用中。

 编译和上传的方法请参考向JavaScript自定义中级开发者的目标前进(3) 〜自动批量上传文件篇〜中所记述内容。

第四行中的应用ID,请根据实际情况更换。

import { KintoneRestAPIClient } from '@kintone/rest-api-client';

// 请输入商品列表的应用ID
const productsAppId = 122;

const events = ['app.record.create.submit', 'app.record.edit.submit'];

kintone.events.on(events, async (event) => {
  const { record } = event;
  
  // 创建一个连接kintone的实例
  const client = new KintoneRestAPIClient();
  
  // 这次为了简便,表中的商品不允许重复。
  // 只是简易的重复检查,不理解也没关系。
  const hasDuplicatedRow = record.报价明细.value.some((rowA, indexA, arr) => {
    return arr.find((rowB, indexB) => indexA !== indexB && rowA.value.型号.value === rowB.value.型号.value);
  })
  if (hasDuplicatedRow) {
    event.error = '不允许选择重复的商品';
    return event;
  }
  
  // 获取表中的商品记录
  let products;
  try {
    products = await client.record.getRecords({
      app: productsAppId,
      query: `型号 in (${record.报价明细.value.map((row) => `"${row.value.型号.value}"`).join(', ')})`,
    });
  } catch (error) {
    event.error = '获取记录失败';
    return event;
  }
  
  // 在商品列表的库存中减去相应数量
  const deductedProductRecords = products.records.map((productRecord) => {
    const tableRow = record.报价明细.value.find((row) => productRecord.型号.value === row.value.型号.value);
    
    // 存放型号值和计算后的库存值
    return {
      型号: {
        value: productRecord.型号.value,
      },
      在库数量: {
        value: Number(productRecord.在库数量.value) - Number(tableRow.value.数量.value),
      },
    };
  });
  
  // 计算后的库存值是否有小于0的情况
  const noStockRecords = deductedProductRecords.filter((productRecord) => Number(productRecord.在库数量.value) < 0);
  
  // 存在1条以上记录时报错并跳过保存
  if (noStockRecords.length > 0) {
    // event.error中存放错误信息后返回
    // 列出出问题的商品型号
    event.error = `存在库存不够的商品。型号 ${noStockRecords
      .map((productRecord) => productRecord.型号.value)
      .join(', ')}`;
      
    return event;
  }
  
  // 没有问题的话更新
  try {
    await client.record.updateRecords({
      app: productsAppId,
      records: deductedProductRecords.map((productRecord) => {
        return {
          updateKey: {
            field: '型号',
            value: productRecord.型号.value,
          },
          record: {
            在库数量: {
              value: productRecord.在库数量.value,
            },
          },
        };
      }),
    });
  } catch (error) {
    event.error = `更新失败 ${error.message}`;
    return event;
  }
  
  return event;
});

上传完成后,确认下有没有实现预想功能。

结束语

直接使用kintone的JavaScript API虽然一点问题也没有,但是如果使用kintone REST API Client的话,可以更简单的实现数据的存取。非常推荐您尝试一下。

此Tips在2020年10月版的 kintone、@kintone/rest-api-client@1.7.0 中确认过。

附件:商品报价合辑包.zip • 27.74KB • 下载