解析URL参数中的定界和嵌套字段名称以获得部分响应 [英] Parse delimited and nested field names from URL parameter for partial response

查看:116
本文介绍了解析URL参数中的定界和嵌套字段名称以获得部分响应的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在基于 Flask-RESTful 的API中,我想允许客户端通过?fields = ... 部分地检索JSON响应.参数.它列出了字段名称(JSON对象的键),这些字段名称将用于构造较大的原始文件的部分表示形式.

In a Flask-RESTful based API, I want to allow clients to retrieve a JSON response partially, via the ?fields=... parameter. It lists field names (keys of the JSON object) that will be used to construct a partial representation of the larger original.

这可能是最简单的逗号分隔列表:

This may be, in its simplest form, a comma-separated list:

GET /v1/foobar?fields=name,id,date

可以使用webargs的DelimitedList 架构字段很容易,对我来说没有问题.

That can be done with webargs' DelimitedList schema field easily, and is no trouble for me.

但是,为了允许表示嵌套对象的键,定界字段列表可能包括任意嵌套在匹配括号内的键:

But, to allow nested objects' keys to be represented, the delimited field list may include arbitrarily nested keys enclosed in matching parentheses:

GET /v1/foobar?fields=name,id,another(name,id),date
{
  "name": "",
  "id": "",
  "another": {
    "name": "",
    "id": ""
  },
  "date": ""
}

GET /v1/foobar?fields=id,one(id,two(id,three(id),date)),date
{
  "id": "",
  "one": {
    "id: "",
    "two": {
      "id": "",
      "three": {
        "id": ""
      },
      "date": ""
    }
  },
  "date": ""
}

GET /v1/foobar?fields=just(me)
{
  "just": {
    "me: ""
  }
}


我的问题有两个:


My question is two-fold:

  1. 是否可以通过本机的 webargs Marshmallow 来执行此操作(验证和反序列化)?

  1. Is there a way to do this (validate & deserialize) with webargs and marshmallow natively?

如果没有,我该如何使用像 pyparsing 这样的解析框架来做到这一点?高度赞赏有关BNF语法的外观的任何提示.

If not, how would I do this with a parsing framework like pyparsing? Any hint on what the BNF grammar is supposed to look like is highly appreciated.

推荐答案

Pyparsing具有几个有用的内置函数,分别是 delimitedList nestedExpr .这是一个带注释的代码段,可为您的值构建一个解析器.(我还提供了一个示例,其中您的列表元素可能不仅仅是简单的字母词):

Pyparsing has a couple of helpful built-ins, delimitedList and nestedExpr. Here is an annotated snippet that builds up a parser for your values. (I also included an example where your list elements might be more than just simple alphabetic words):

import pyparsing as pp

# placeholder element that will be used recursively
item = pp.Forward()

# your basic item type - expand as needed to include other characters or types
word = pp.Word(pp.alphas + '_')
list_element = word

# for instance, add support for numeric values
list_element = word | pp.pyparsing_common.number

# retain x(y, z, etc.) groupings using Group
grouped_item = pp.Group(word + pp.nestedExpr(content=pp.delimitedList(item)))

# define content for placeholder; must use '<<=' operator here, not '='
item <<= grouped_item | list_element

# create parser
parser = pp.Suppress("GET /v1/foobar?fields=") + pp.delimitedList(item)

您可以使用 runTests 测试任何pyparsing表达式:

You can test any pyparsing expression using runTests:

parser.runTests("""
    GET /v1/foobar?fields=name,id,date
    GET /v1/foobar?fields=name,id,another(name,id),date
    GET /v1/foobar?fields=id,one(id,two(id,three(id),date)),date
    GET /v1/foobar?fields=just(me)
    GET /v1/foobar?fields=numbers(1,2,3.7,-26e10)    
    """,  fullDump=False)

赠予:

GET /v1/foobar?fields=name,id,date
['name', 'id', 'date']
GET /v1/foobar?fields=name,id,another(name,id),date
['name', 'id', ['another', ['name', 'id']], 'date']
GET /v1/foobar?fields=id,one(id,two(id,three(id),date)),date
['id', ['one', ['id', ['two', ['id', ['three', ['id']], 'date']]]], 'date']
GET /v1/foobar?fields=just(me)
[['just', ['me']]]
GET /v1/foobar?fields=numbers(1,2,3.7,-26e10)
[['numbers', [1, 2, 3.7, -260000000000.0]]]

这篇关于解析URL参数中的定界和嵌套字段名称以获得部分响应的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆