[{"data":1,"prerenderedAt":241},["ShallowReactive",2],{"content:\u002Fposts\u002F2026\u002Fbff-in-brief":3,"surround:\u002Fposts\u002F2026\u002Fbff-in-brief":229},{"id":4,"title":5,"body":6,"canonical":206,"categories":207,"date":209,"description":210,"draft":211,"extension":212,"image":206,"meta":213,"navigation":214,"path":215,"permalink":206,"readingTime":216,"recommend":206,"references":206,"seo":221,"sitemap":222,"stem":223,"tags":224,"type":206,"updated":209,"__hash__":228},"content\u002Fposts\u002F2026\u002FBFF-in-brief.md","BFF简述",{"type":7,"value":8,"toc":198},"minimark",[9,17,22,30,46,49,66,69,72,77,83,87,109,112,120,125,129,134,139,145,150,159,168,174,187,193],[10,11,13],"alert",{"type":12},"info",[14,15,16],"p",{},"后端的前端，还是前端的后端？",[18,19,21],"h2",{"id":20},"bff-是什么","BFF 是什么？",[14,23,24,25,29],{},"BFF(",[26,27,28],"code",{"code":28},"Backend For Frontend",") 的核心思想是：为每个前端界面或平台创建一个专属的轻量级后端服务，该服务负责：",[31,32,33,37,40,43],"ul",{},[34,35,36],"li",{},"聚合来自多个微服务的数据；",[34,38,39],{},"对数据进行裁剪、转换、格式化，以适配特定前端的需求；",[34,41,42],{},"处理与 UI 逻辑紧密相关的业务逻辑（如页面组装、权限控制等）；",[34,44,45],{},"避免前端直接调用多个后端微服务。",[14,47,48],{},"比如有以下几个场景：",[50,51,52,55],"ol",{},[34,53,54],{},"你有一个大屏的项目，需要在页面展示时获取很多图表的数据。此时 API 端已经有数据，但是很零散，他们也没有时间来做数据整合",[34,56,57,58,61,62,65],{},"API 端已经有数据接口，但是 ",[26,59,60],{"code":60},"WEB"," 和 ",[26,63,64],{"code":64},"移动端"," 的展示逻辑不同，而且可能有不同的数据需求",[14,67,68],{},"如果要在现有服务端直接进行更改，可能会有很多的改动。在前端变化频繁的时候，后端也需要频繁的进行改动。",[14,70,71],{},"这时候就可以用到 BFF 了，它可以为每个端做不同的事，将一些数据整个的事放到指定的服务中。",[73,74],"pic",{"caption":75,"src":76},"BFF架构示意图","https:\u002F\u002Fbitmc.uno\u002Fpicgo\u002FBFF.jpg",[78,79,80],"blockquote",{},[14,81,82],{},"在微服务架构中，后端会被分为多个服务，不同的数据会在不同的服务中存在。BFF 也可以看做是一个独立的微服务。",[18,84,86],{"id":85},"为什么需要-bff","为什么需要 BFF",[50,88,89,92,100,103,106],{},[34,90,91],{},"有时候一个接口会返回过多或者过少的数据，无法满足前端的需要。前端可能需要调用多个接口来组合，会增加前端的复杂度。",[34,93,94,95],{},"可以提升一些性能: 将之前多个请求降低为单个请求，并且可以在 BFF 中将之前使用 HTTP 请求改为使用更加快速的 RPC，并且可以在 BFF 层裁剪不需要的数据\n",[10,96,97],{},[14,98,99],{},"RPC (Remote Procedure Call) 远程过程调用是一种通信协议，允许程序在不同计算机上执行代码，就像调用本地函数一样，隐藏了底层网络通信细节，广泛用于构建微服务和分布式系统，实现高效、透明的远程服务调用。它通过客户端-服务器模式工作，客户端发起调用，服务器响应，通常比HTTP更适合内部服务间的高性能通信",[34,101,102],{},"多端返回不同的数据: WEB 端可能需要比较完整的数据，移动端需要更加精简的数据。",[34,104,105],{},"降低对服务器的压力: 可以在 BFF 层设置缓存(如： Redis)，在有缓存时直接访问缓存",[34,107,108],{},"纯后端和前端进行解耦: 服务端可以不太关注前端需要的数据，数据可以在 BFF 中进行裁剪组合",[18,110,111],{"id":111},"可能出现的问题",[50,113,114,117],{},[34,115,116],{},"增加复杂度: 只要增加一层肯定会增加复杂度，增加运维压力",[34,118,119],{},"责任归属问题: BFF 到底归属于前端团队还是后端团队？这部分的责任归属如何分配？",[78,121,122],{},[14,123,124],{},"最佳实践：将 BFF 视为“前端的一部分”，由前端或全栈团队维护；保持其轻量、无状态、聚焦 UI 数据组装。",[18,126,128],{"id":127},"我实际遇到的-bff-层的应用","我实际遇到的 BFF 层的应用",[50,130,131],{},[34,132,133],{},"小程序H5上传文件的 URL 获取",[31,135,136],{},[34,137,138],{},"小程序中使用 H5上传文件，上传后获取文件的 URL 并且在小程序中展示",[50,140,142],{"start":141},2,[34,143,144],{},"小程序|H5 城市数据的获取",[31,146,147],{},[34,148,149],{},"中国城市的经纬度和编号获取。直接放到前端后，打包体积会变大。放到 BFF 层中进行获取。结合 Redis 缓存，打包体积减小并且访问速度和使用静态文件也没有很大的差距。",[50,151,153,156],{"start":152},3,[34,154,155],{},"Excel数据转换和文件导出",[34,157,158],{},"获取拼音首字母",[31,160,161],{},[34,162,163,164,167],{},"和 ",[26,165,166],{"code":166},"第2条"," 一样，减少前端的打包体积。",[50,169,171],{"start":170},5,[34,172,173],{},"使用 puppeteer 将 HTML 转为 image 或 PDF",[31,175,176],{},[34,177,178,179,182,183,186],{},"有将指定的页面转换为",[26,180,181],{"code":181},"图片","或者",[26,184,185],{"code":185},"PDF","的需求，使用 puppeteer 很方便，并且可以给不同的几个项目提供此能力。",[50,188,190],{"start":189},6,[34,191,192],{},"经纬度转换为物理地址",[31,194,195],{},[34,196,197],{},"这个有第三方的 API，可以在 BFF 层中进行获取。因为它用到了第三方提供的 SECRET 和 KEY（放到前端可能会被盗刷），并且后端不需要此数据，所以都放到 BFF 层中进行获取。",{"title":199,"searchDepth":200,"depth":200,"links":201},"",4,[202,203,204,205],{"id":20,"depth":141,"text":21},{"id":85,"depth":141,"text":86},{"id":111,"depth":141,"text":111},{"id":127,"depth":141,"text":128},null,[208],"代码","2026-01-03 17:02:06","BFF 是一种常见的架构模式，用于为不同类型的前端客户端提供定制化的后端服务。",false,"md",{},true,"\u002Fposts\u002F2026\u002Fbff-in-brief",{"text":217,"minutes":218,"time":219,"words":220},"6 min read",5.445,326700,1089,{"title":5,"description":210},{"loc":215},"posts\u002F2026\u002FBFF-in-brief",[225,226,227],"BFF","架构模式","扩展阅读","YMBEQKDXiCY1A5jA0v6u7rnWRoF7MddnPLjUNWCbfiI",[230,236],{"title":231,"path":232,"stem":233,"date":234,"type":235,"children":-1},"2025年终总结","\u002Fposts\u002F2025\u002F2025-year-end-summary","posts\u002F2025\u002F2025-year-end-summary","2025-12-31 15:35:20","story",{"title":237,"path":238,"stem":239,"date":240,"type":206,"children":-1},"HTTP 状态码和短语","\u002Fposts\u002F2026\u002Fhttp-status-codes-and-phrases-cheat-sheet","posts\u002F2026\u002Fhttp-status-codes-and-phrases-cheat-sheet","2026-01-04 11:15:21",1789642587803]