When using SimpleIO in a service, if we are returning a list of dictionaries, we shall use:
output_repeated = True attribute in the SimpleIO class.
self.response.payload[:] = output in the service.
In this type of service, we know the attributes present in the dictionary (id, name, surname, etc.) but we don’t know how many rows we’ll be returning (from zero to a lot). So, how should we configure output_required and output_optional in the SimpleIO class?
For example:
# Channel GET /app/customers calls customer.get-customer
class GetCustomers(Service):
class SimpleIO:
input_required = ()
output_optional = ('id', 'name', 'surname', 'email', ...)
output_repeated = True
def handle(self):
conn = self.kvdb.conn.get('app:database:conn')
with closing(self.outgoing.sql.get(conn).session()) as session:
self.response.payload[:] = session.query(Customer).order_by(Customer.id)
Would we be using output_optional or output_required in this example?
You can use output_required for keys that you know for 100% that will be available on output, that is, you guarantee that they will exist in each dictionary. In case they are missing, an exception will be raised - this is validation of output in other words.
On the other hand, you can use output_optional if you are not sure if a given key will be available in each dictionary.
So, in summary, output_required and output_optional:
When returning a single dictionary, they validate the keys of such dictionary, as you’ve described in your reply.
When returning a list of dictionaries, they validate the keys of each dictionary in the list (the same way you’ve described before but for each tuple).
And using output_required or output_optional depends on what you consider the minimum and maximum number of fields in the dictionary (useful when support field projections on resources, I guess).
Yes, this is correct and I would only add that the emphasis is on which keys are returned. E.g. your SQLAlchemy models returned by a particular query may have thirty attributes but with SIO you may want to return only six specific ones. Same goes for dictionary keys.
When the client uses fields projection to get a subset of fields (e.g. just the name and the surname), the resulting JSON has a lot of empty keys. When no fields projection is used, the returned JSON is just fine.
So, is there a way to dinamically change the value of output_required when the code detects a valid use of the fields parameter?
Looks good though instead of output_repeat it would be output_repeated and you do not need to declare anything if you do not use it, i.e. input_required can be omitted unless you meant for this class to be subclassed and for children classes to append to it, e.g.:
class BaseSIO:
input_required = ()
output_required = ('abcd', 'efgh')
class ChildSIO(BaseSIO):
input_required = BaseSIO.input_required + ('elem1', 'elem2')