Comments (5)
It looks that option 1. is as simple as:
index 25728e3..6368521 100644
--- a/src/graceful/serializers.py
+++ b/src/graceful/serializers.py
@@ -64,7 +64,7 @@ class MetaSerializer(type):
)
-class BaseSerializer(metaclass=MetaSerializer):
+class BaseSerializer(BaseField, metaclass=MetaSerializer):
"""Base serializer class for describing internal object serialization.
Example:
@@ -81,6 +81,8 @@ class BaseSerializer(metaclass=MetaSerializer):
height = FloatField("cat height in cm")
"""
+ def __init__(self, details=None, **kwargs):
+ super().__init__(details=details, **kwargs)
@property
def fields(self):
Here is a small snippet of code that shows how nested resource serializers could be defined and proofs that it works:
from pprint import pprint
from graceful.serializers import BaseSerializer
from graceful.fields import StringField
class Inner(BaseSerializer):
fooX = StringField("Foo field", source='foo')
barX = StringField("Bar field", source='bar')
class Outer(BaseSerializer):
innerX = Inner(details="inner object", source='inner')
nameX = StringField("Name field", source='name')
def main():
outer = Outer()
internal = {
"inner": {
"foo": "something",
"bar": "something else",
},
"name": "my outer"
}
print("\n ====== internal ======")
pprint(internal)
print("\n === representation ===")
pprint(outer.to_representation(internal))
print("\n ====== internal ======")
pprint(outer.from_representation(outer.to_representation(internal)))
if __name__ == "__main__":
main()
And example output:
$ python nested.py
====== internal ======
{'inner': {'bar': 'something else', 'foo': 'something'}, 'name': 'my outer'}
=== representation ===
{'innerX': {'barX': 'something else', 'fooX': 'something'}, 'nameX': 'my outer'}
====== internal ======
{'inner': {'bar': 'something else', 'foo': 'something'}, 'name': 'my outer'}
But the problem is in how we will handle "describe()" methods in serializers. If they are fields now we should make them described the same way as fields so with "details", "type", "label", "spec", "read_only" attributes. Right now we put all definition to "fields" dictionary of resource metadata dict but we cannot handle this that way anymore.
I think we could utilise serializer class docstring as a field details and completely change the overall layout of description output. Instead of having single fields
dict in the resource metadata we could have something more nested:
{
...,
'representation': { # => result of serializer.describe()
'details': ... # => serializers docstring
'label': ... # => optional label for consistency
'spec': ... # => spec, here developer can add link for docs in case of nested serializers
'type': 'representation', # => optionally 'object'/'dict' to inform it is another dict
'fields': { # => content of former 'fields' dictionary
{ # example of single field like str, int, float etc.
'details': ...
'label': ...
'spec': ...
'type': ....
# => in case of simple fields there is no 'fields' key
},
{ # example of field coming from different serializer
'details': ...
'label': ...
'spec': ...
'type': 'representation'
'fields': {...} # => fields that are serializers will have the same description
},
},
},
}
Alternative way of handling nested descriptions is utilisation of spec
field attribute that will now
come really handy. We could assume that resource description structure stays as it is (flat fields
dict) and whenever we include serializer as a field the user should supply spec
with the link of nested resource documentation. Because resources are self-descriptive (full metadata on OPTIONS request) this can be simply a link to URI of separate nested resource endpoint.
Pros:
- if user would like to create mutually nested resources (it is possible) we will not end up with infinite description loop
- it makes possible auto documenters simpler beach they will not need to deal with nested fields descriptions
- it does not require backwards incompatible changes
Cons:
- it will be harder to describe nested resources that do not have their own query endpoints
For the problem with describing nested resources that do not have their now API there is a simple solution. One could create virtual endpoint that serves only documentation purpose. It would accept only OPTIONS requests to serve specification but would not deliver any of other manipulation methods (GET/POST/PUT/DELETE).
Also the main reason for having nested resource capabilities is a use case when serializer that is nested is actually reused in some other existing resource endpoint.
from graceful.
Seems like with the new validation in 1.0.0
version it will be even simpler and more clear. Other problem that have surfaced is how to present validation issues in nested representations and representations that have fields with many=True
enables. We need to came up with some new format for validation issues that.
from graceful.
Hi, i am trying to do a nested serialization. My project is using peewee as orm, i am trying to fetch a list of awards with a nested user on the results set.
class AwardListSerializer(BaseSerializer):
redeemed_at = IntField("Date when the award was redeemed.")
user = UserSerializer()
This code is not working, my response is returning this:
{
"meta": {
"params": {
"indent": 0,
"page_size": 10,
"page": 0
},
"length": 1,
"total_items": 1,
"page_size": 10,
"page": 0,
"prev": null,
"next": "page=1&page_size=10"
},
"content": [
{
"redeemed_at": null
}
]
}
I don't know if i am doing something wrong or what. I saw the test with the example to achieve it, but i can't use details neither source params on the constructor of my nested serializer.
Any clue or help i'll be very grateful.
Regards
from graceful.
@holic-cl, there is little hiatus in this projects. As far as I remember, the proposed change was never included and released. It's mostly because I had no idea how to approach the problem of nested resource descriptions returned from .describe()
handler.
Still, this feature is mostly complete so if we agree on some format, I could apply the patch, modify the handlers and release such feature as part of 1.x version.
from graceful.
Oh, ok, thanks for answer.
from graceful.
Related Issues (20)
- Consider getting rid of default param value in "raw" or at least deserialising it only once HOT 3
- Problem: incompatibility with falcon hooks
- Problem: No easy way to create custom per-request context HOT 1
- Add docs section about mixins
- Add missing "version added" and "version changed" specifiers for all previous features and releases
- librelist doesnt seem to work HOT 1
- Rewrite tests in test_generic to pytest-style HOT 1
- 405 when using PUT method HOT 1
- Field validation error uses field source names instead of representation names.
- Writable *-sourced fields break object validation on POST/PUT/PATCH HOT 2
- Support for star-like writable fields HOT 1
- Add "write_only" fields
- Improperly handled fields with many=True
- Better validation error representation.
- Mark all keyword arguments in BaseField as keyword only
- Auth: allow to set detailed authorization requirements for specific HTTP methods
- Revisit terminology and class names.
- Support for serializer's method fields.
- A StringField's value become "None" instead of None when client submit it as null. HOT 5
- Support for OpenApi Generator's graceful generator? HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from graceful.