In the Open Event API Server project attributes of the API are dasherized.
What was the need for dasherizing the attributes in the API ?
All the attributes in our database models are separated 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 set up for them was the primary reason behind this decision.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.
Note: The dasherized version for first_name will be first-name.
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 is 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_APIwas 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 []
Related links:
- Marshmallow-json-api: http://marshmallow-jsonapi.readthedocs.io/en/latest/
- Json-api spec naming recommendations: http://jsonapi.org/recommendations/#naming
- Flask-rest-jsonapi Github repo: https://github.com/miLibris/flask-rest-jsonapi