You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于SCIM API使用attributes和excludedAttributes编辑JSON的通用方案

通用解决方案:SCIM API中使用attributes/excludedAttributes编辑JSON响应

先从你给出的具体场景入手,直观理解需求:
原始响应:

{
  "emails": [
    { "type": "work", "value": "bjensen@example.com" }
  ],
  "id": "2819c223-7f76-453a-919d-413861904646",
  "phoneNumbers": [
    { "type": "work", "value": "555-555-8377" },
    { "type": "business", "value": "555-555-8377" }
  ],
  "schemas": [ "urn:scim:schemas:core:1.0" ],
  "userName": "bjensen"
}

当传入参数 excludedAttributes=phoneNumbers.type 时,期望得到的过滤后响应:

{
  "emails": [
    { "type": "work", "value": "bjensen@example.com" }
  ],
  "id": "2819c223-7f76-453a-919d-413861904646",
  "phoneNumbers": [
    { "value": "555-555-8377" },
    { "value": "555-555-8377" }
  ],
  "schemas": [ "urn:scim:schemas:core:1.0" ],
  "userName": "bjensen"
}

下面是适配所有SCIM场景的通用实现思路,核心是处理属性路径解析与嵌套结构的递归过滤:

1. 解析属性参数

不管是attributes(指定保留属性)还是excludedAttributes(指定排除属性),第一步要把参数转成可遍历的层级路径:

  • 先分割逗号分隔的参数值,比如excludedAttributes=phoneNumbers.type,emails.type会拆成["phoneNumbers.type", "emails.type"]
  • 再把每个路径拆成层级节点数组,比如phoneNumbers.type拆成["phoneNumbers", "type"],方便后续遍历嵌套JSON结构

2. 递归遍历并过滤JSON

需要写一个递归函数处理对象和数组两种核心结构:

  • 处理对象:遍历每个键,判断当前键对应的路径是否符合保留/排除规则。如果是排除规则匹配则跳过该键;如果是包含规则,只有匹配的键才保留。
  • 处理数组:对数组中的每个元素递归调用过滤函数——毕竟SCIM里的数组元素大多是嵌套对象(比如phoneNumbers的每个条目),得逐个处理内部属性。

3. 遵循SCIM规范的参数优先级

根据SCIM官方规范,attributes的优先级高于excludedAttributes:

  • 如果同时传入两个参数,先按attributes保留指定属性,再在这个结果上应用excludedAttributes做二次排除
  • 如果只传attributes,仅保留指定路径的所有层级属性
  • 如果只传excludedAttributes,保留所有属性除了指定路径的属性

4. 简化实现示例(JavaScript)

这里给一个可直接参考的代码片段,你可以根据自己的技术栈调整:

function filterSCIMResponse(data, attributes = [], excludedAttributes = []) {
  // 把参数路径解析为层级数组
  const parsePaths = (paths) => paths.map(path => path.split('.'));
  
  const attrPaths = parsePaths(attributes);
  const excludePaths = parsePaths(excludedAttributes);

  // 递归过滤核心函数
  const filterNode = (node, currentPath = []) => {
    if (Array.isArray(node)) {
      return node.map(item => filterNode(item, currentPath));
    }
    if (typeof node !== 'object' || node === null) {
      return node;
    }

    const filteredObj = {};
    Object.keys(node).forEach(key => {
      const newPath = [...currentPath, key];
      // 判断是否符合包含规则(若传入了attributes)
      const isIncluded = attributes.length === 0 || attrPaths.some(path => {
        return path.slice(0, newPath.length).join('.') === newPath.join('.');
      });
      // 判断是否符合排除规则
      const isExcluded = excludePaths.some(path => {
        return path.join('.') === newPath.join('.');
      });

      if (isIncluded && !isExcluded) {
        filteredObj[key] = filterNode(node[key], newPath);
      }
    });
    return filteredObj;
  };

  return filterNode(data);
}

// 使用示例
const originalResponse = { /* 你的原始SCIM响应数据 */ };
const filteredResult = filterSCIMResponse(originalResponse, [], ['phoneNumbers.type']);
console.log(filteredResult);

额外注意事项

  • 要兼容SCIM中的多层嵌套属性,比如name.givenName这类深层路径
  • 处理数组时要注意空数组、非对象数组的边界情况
  • 严格遵循SCIM规范的参数优先级,避免逻辑冲突

内容的提问来源于stack exchange,提问作者Bush

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:51:02