API设计最佳实践:使用json_build_object

时间:2020-05-06 06:49:22

标签: django rest django-rest-framework

我正在开发基于Web的应用程序,该应用程序实现以下内容:

  1. PostgreSQL RDBMS非ORM数据库
  2. 用于在后台设计和处理数据序列化程序和API请求的Django Rest框架
  3. 对于GET方法,将SQL SELECT查询设计为具有类似json的结构 使用json_build_object

在数据库中

person(personid, fullname, cityid)
city(cityid, cityname, countryid)
country(countryid, countryname)

在SERIALIZER中

class CountrySerializer(serializers.Serializer):
 id=serializers.IntegerField()
 name=serializers.CharField()

class CitySerializer(serializers.Serializer):
 id=IntegerField()
 name=CharField()
 country=CountrySerializer()

class PersonSerializer(serializers.Serializer):
 id=IntegerField()
 person=CharField()
 city=CitySerializer()

在API视图中

from .custom_utils import raw_sql_select

class APIView_Person(generics.GenericAPIView):
  serializer_class = PersonSerializer
  permission_classes = (IsAuthenticatedOrReadOnly,)
  def get_queryset(self):
   query=("""
    SELECT
     p.personid as id,
     p.fullname as person,
     json_build_object(
      'id',ct.cityid,
      'name',ct.cityname,
      'country',json_build_object(
        'id',cntry.countryid,
        'name',cntry.countryname
       )
     ) AS city
     FROM persons p
     JOIN city ct ON ct.cityid=p.cityid
     JOIN country cntry ON cntry.countryid=ct.countryid
   """)
   return raw_sql_select(query, "db_connection")

  def get(self, request):
   rows = [
    {
      "id": col.id,
      "person": col.person,
      "city": col.city
    } for col in self.get_queryset()[1]
   ]
   results = PersonSerializer(rows, many=True).data
   return Response(results or [])

前沿

const [state, setState] = useState({
 personList: []
})

useEffect(()=>{
  fetch('/api/persons/', {method: 'GET', headers:{'Content-Type':'application/json'}})
  .then(res=>res.json())
  .then(rows=>setState(states=>({...states,personList:rows})))
}, [])

return(
 <>
  <Typography variant="body1" component="p">{state.person}</Typography>
  <Typography variant="caption" component="p" color="textSecondary">{state.city}, {state.city.country} 
  </Typography>
 </>
)

这是我目前设计API的方式。

  1. 为什么要使用原始sql查询?因为我使用的不是在Django应用程序中创建的数据库,所以我没有用于实现Django ORM的模型。
  2. 为什么我的查询的结构类似于json?因为我使用的序列化程序不依赖模型,也不扩展ModelSerializer类。

我的问题是:

  1. 这是一种好方法吗?
  2. 如果数据库结构发生更改,这种设计是否会在可维护性方面带来未来的问题?
  3. 如果我将CountrySerializer()从name = CharField()更改为country_name = CharField(),那么将我的API后端逻辑更改为将响应的对象键从“ name”返回到“ country_name”,并且我有20个前端模块对旧“名称”对象键的引用-那么大概我必须编辑这20个前端模块以将“名称”引用更改为“ country_name”。 这种类型的维护是否不可避免,并且被认为是RESTFul API中常见的可能遇到的问题?

0 个答案:

没有答案