Supporting Kebab-Case Attributes And Query Params In Flask-Rest Jsonapi
In the Open Event API Server Project, it was decided to dasherize all the attributes of the API.
What Was The Need For Dasherizing The Attributes In The API ?
All the attributes in our database models are seperated by underscores i.e first name
would be stored as first_name
. But most of the API client implementations support dasherized attributes by default. In order to attract third party client implementations in the future and making the API easy to setup for them was the primary reason behind this decision. Note: The dasherized version for first_name
will be first-name
. Also to quote the official json-api spec recommendation for the same:
Member names SHOULD contain only the characters “a-z” (U+0061 to U+007A), “0-9” (U+0030 to U+0039), and the hyphen minus (U+002D HYPHEN-MINUS, “-“) as separator between multiple words.
flask-rest-jsonapi is the API framework used by the project. We were able to dasherize the API responses and requests by adding inflect=dasherize
to each API schema, where dasherize
iss the following function:
def dasherize(text):
return text.replace('_', '-')
flask-rest-jsonapi also provides powerful features like the following through query params:
But we observed that the query params were not being dasherized which rendered the above awesome features useless :( . The reason for this was that flask-rest-jsonapi took the query params as-is
and search for them in the API schema. As Python variable names cannot contain a dash, naming the attributes with a dash in the internal API schema was out of the question.
For adding dasherizing support to the query params, change in the QueryStringManager
located at querystring.py
of the framework root are required. A config variable named DASHERIZE_API
was added to turn this feature on and off.
Following Are The Changes Required For Dasherizing Query Params:
For Sparse Fieldsets in the fields
function, replace the following line:
result[key] = [value]
with
if current_app.config['DASHERIZE_API'] is True:
result[key] = [value.replace('-', '_')]
else:
result[key] = [value]
For sorting, in the sorting
function, replace the following line:
field = sort_field.replace('-', '')
with
if current_app.config['DASHERIZE_API'] is True:
field = sort_field[0].replace('-', '') + sort_field[1:].replace('-', '_')
else:
field = sort_field[0].replace('-', '') + sort_field[1:]
For Include related objects, in include
function, replace the following line:
return include_param.split(',') if include_param else []
with
if include_param:
param_results = []
for param in include_param.split(','):
if current_app.config['DASHERIZE_API'] is True:
param = param.replace('-', '_')
param_results.append(param)
return param_results
return []