简体   繁体   English

如何使用Ramda js规范对特定结构的Api响应

[英]How to normalize Api response to particular structure using Ramda js

Suppose we have some nested and unNormalized data coming from Api, how i can simplify the response using Ramda so that it can be used in easy way in fron end apps. 假设我们有一些来自Api的嵌套和非规范化数据,我如何使用Ramda简化响应,以便可以在fron终端应用程序中轻松使用它。

Convert this response 转换此回复

{
  articles: [
    {
      id: 1,
      title: "Dagon",
      tags: [{ id: 1, name: "old ones" }, { id: 2, name: "short story" }]
    },
    {
      id: 2,
      title: "Azathoth",
      tags: [{ id: 1, name: "old ones" }, { id: 3, name: "novel" }]
    },
    {
      id: 3,
      title: "At the Mountains of Madness",
      tags: [{ id: 4, name: "insanity" }, { id: 3, name: "novel" }]
    }
  ]
}

to

{
  articles: {
    byId:{
        1: { title: "Dagon", tags: [1, 2] },
        2: { title: "Azathoth", tags: [1, 3] },
        3: { title: "At the Mountains of Madness", tags: [3, 4] }
    },
    allIds:[1,2,3]
  },
  tags: {
        byId:{
        1: "old ones",
        2: "short story",
        3: "novel",
        4: "insanity"
        },
        allIds:[1,2,3,4]
  }
}

I would probably write it like this: 我可能会这样写:

 const articles = R.pipe( R.prop('articles'), R.applySpec({ allIds: R.pluck('id'), byId: R.pipe( R.groupBy(R.prop('id')), R.map( R.pipe( R.head, R.evolve({ tags: R.pluck('id') }), R.dissoc('id'), ), ), ), }), ); const tags = R.pipe( R.prop('articles'), R.pluck('tags'), R.flatten, R.uniqBy(R.prop('id')), R.applySpec({ allIds: R.pluck('id'), byId: R.pipe( R.groupBy(R.prop('id')), R.map(R.path([0, 'name'])), ), }), ); const normalize = R.applySpec({ tags, articles }); const data = { articles: [ { id: 1, title: "Dagon", tags: [ { id: 1, name: "old ones" }, { id: 2, name: "short story" }, ], }, { id: 2, title: "Azathoth", tags: [ { id: 1, name: "old ones" }, { id: 3, name: "novel" }, ], }, { id: 3, title: "At the Mountains of Madness", tags: [ { id: 4, name: "insanity" }, { id: 3, name: "novel" }, ], }, ], }; console.log('result', normalize(data)); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script> 

This is interesting because usually have the opposite problem: I have normalized data from a service that I want to de-normalize on the client. 这很有趣,因为通常会有相反的问题:我已经从服务中标准化了数据,而我想在客户端上对其进行反标准化。 I can see how this can arise, but it's different from my experience. 我可以看到这是怎么发生的,但这与我的经验不同。

I would probably write it like this: 我可能会这样写:

 const articles = pipe( prop('articles'), reduce((a, {id, title, tags}) => ({...a, [id]: {title, tags: pluck('id', tags)}}), {}) ) const tags = pipe( prop('articles'), pluck('tags'), flatten, reduce((a, {id, name}) => ({...a, [id]: name}), {}) ) const normalize = (resp, as = articles(resp), ts = tags(resp)) => ({ articles: {byId: as, ids: keys(as)}, tags: {byId: ts, ids: keys(ts)} }) const resp = {articles:[{id:1,title:"Dagon",tags:[{id:1,name:"old ones"},{id:2,name:"short story"}]},{id:2,title:"Azathoth",tags:[{id:1,name:"old ones"},{id:3,name:"novel"}]},{id:3,title:"At the Mountains of Madness",tags:[{id:4,name:"insanity"},{id:3,name:"novel"}]}]}; console.log(normalize(resp)) 
 <script src="https://bundle.run/ramda@0.26.1"></script><script> const {pipe, prop, reduce, pluck, flatten, keys} = ramda </script> 

The reduce step in tags could be replaced by map(values), fromPairs , but that feels like a hack, as it depends on the order of the properties in the tags. tagsreduce步骤可以由map(values), fromPairsmap(values), fromPairs ,但这听起来像是map(values), fromPairs ,因为它取决于标签中属性的顺序。

One difference from your requested output is that I keep the tag ids in the original order of the tags for the article. 与您请求的输出的不同之处在于,我将标签ID保持为文章标签的原始顺序。 Thus article 3 has tags [4, 3] instead of your [3, 4] . 因此, article 3具有标签[4, 3]而不是您的[3, 4] I think this makes more sense, as it's possible that there is some intrinsic ordering to tags, but obviously if you don't like that, you could simply add a sort step. 我认为这更有意义,因为标签可能有一些固有的顺序,但是显然,如果您不喜欢这样做,则可以简单地添加一个sort步骤。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM