一、BFF架构简介

BFF(Browser/Backend-For-Frontend)架构,即面向前端的后端,是一种将前后端分离的思想顺畅地解决了前后端耦合导致的问题。在传统的MVC架构中,一旦后端的某个接口返回的数据格式改变,前端需要同时进行修改,维护成本较高。而BFF架构通过为每个前端提供专属的后端服务接口,充分利用了后端的数据处理能力,解决了前后端耦合的问题,有效提高了开发效率和系统的可维护性。BFF架构的主要优势包括高效灵活、易维护等。

二、BFF架构的优势

1、高效

在BFF架构中,后端服务根据前端的需求,为每个前端提供专属的服务,从而减少了无用数据的传输,降低了网络带宽的占用。此外,不同的前端可以共享一个后端服务,进一步提高了BFF架构的效率。


// 示例代码
app.get('/user/:id', function (req, res) {
  var userId = req.params.id;
  var user = users[userId]
  if (user) {
    res.send(user)
  } else {
    res.status(404).send('User not found')
  }
})

2、灵活

BFF架构允许不同的前端服务共享同一个后端接口,因此可以灵活定制不同的用户体验。比如在web端和手机端应用共享同一个后端接口,还可以为web端提供专属的数据格式和风格,可以为手机端提供更轻量的接口和更易于操作的界面。


// 示例代码
app.get('/user/:id', function (req, res) {
  var userId = req.params.id;
  var user = users[userId]
  if (user) {
    if (req.get('User-Agent').indexOf('Android') != -1) {
      res.send({ name: user.name, id: user.id, mobile: user.mobile })
    } else {
      res.send({ name: user.name, id: user.id, email: user.email })
    }
  } else {
    res.status(404).send('User not found')
  }
})

3、易维护

BFF架构将前后端分离,不再需要在前端和后端之间进行频繁的修改和更新,只需要在BFF层进行服务接口的维护和更新。同时,BFF层可以根据实际需求进行模块化设计和分层架构,在BFF层组织代码结构,降低了系统的复杂性,便于后期维护。


// 示例代码
// users.api.js
export default {
  getUserById: (id) => {
     return axios.get(`/users/${id}`)
  },
  updateUserById: (id, user) => {
     return axios.put(`/users/${id}`, user)
  },
}

// users.service.js
import usersApi from './users.api'
export default {
  getUserById: (id) => {
     return usersApi.getUserById(id)
  },
  updateUserById: (id, user) => {
     return usersApi.updateUserById(id, user)
  },
}

三、BFF架构的实战应用

BFF架构在实际应用中具有广泛的适用性,可以在各种应用场景中发挥其优势。比如在电商应用中,可以将BFF层与购物车、订单、支付等服务进行整合,为不同的客户端提供专属的功能接口;在社交应用中,可以与用户、消息、好友等服务进行整合,提供丰富的社交功能。

下面是一个简单的实战示例:


// users.api.js
export default {
  getUserById: (id) => {
     return axios.get(`/users/${id}`)
  },
  updateUserById: (id, user) => {
     return axios.put(`/users/${id}`, user)
  },
}

// users.service.js
import usersApi from './users.api'
export default {
  getUserById: (id) => {
     return usersApi.getUserById(id)
  },
  updateUserById: (id, user) => {
     return usersApi.updateUserById(id, user)
  },
}

// cart.api.js
export default {
  getCartByUserId: (userId) => {
     return axios.get(`/cart/users/${userId}`)
  },
  updateCartByUserId: (userId, cart) => {
     return axios.put(`/cart/users/${userId}`, cart)
  },
}

// cart.service.js
import cartApi from './cart.api'
export default {
  getCartByUserId: (userId) => {
     return cartApi.getCartByUserId(userId)
  },
  updateCartByUserId: (userId, cart) => {
     return cartApi.updateCartByUserId(userId, cart)
  },
}

// order.api.js
export default {
  getOrderByUserId: (userId) => {
     return axios.get(`/orders/users/${userId}`)
  },
  createOrderByUser: (userId, order) => {
     return axios.post(`/orders/users/${userId}`, order)
  },
}

// order.service.js
import orderApi from './order.api'
export default {
  getOrderByUserId: (userId) => {
     return orderApi.getOrderByUserId(userId)
  },
  createOrderByUser: (userId, order) => {
     return orderApi.createOrderByUser(userId, order)
  },
}