Open WrathfulSpatula opened 3 years ago
To be clear, my biggest concern at the moment is stripping soft deletion fields from API call results, but also any information that we rightly don't need to tell users. (Ask me, if you're in doubt.)
I suppose I'm less familiar with this concept so the exact task of what should be done here is still a bit unclear to me.
So we should create service/userDto/
and service/submissionDto/
, but it's still not entirely clear what should be placed in these folders. Are we to actually place the JSON result of the respective getSanitized()
methods in each of these folders?
@vprusso We can define classes (like for our web app views and components) that are just a list of specific fields that each getSantized()
method returns on its result object. These "dumb" classes correspond (mostly one-to-one) with our Mongoose model classes. We instantiate these classes in getSanitized()
, and copy model data into them. These DTOs are therefore standardized, lightweight, and safer than directly handling models when we don't need proper models, which could otherwise have side-effects on the database, if we accidentally try to save()
via extension method.
These "dumb" classes specifically have no methods, and all their properties are public, (and serializable). (In other languages, these class fields might be allocated on heap, but I don't think the concept applies to JavaScript.)
Maybe I haven't communicated the idea clearly, but maybe the hard part to understand is the "value added" despite the fact that DTOs don't seem like they do anything. DTOs are just classes that standardize "sanitized" API call return types, with the minimum of information we always want to give back to API users the same way, and with no logic or methods.
(They're similar to the simplest cases you see of ad hoc struct
definitions in C or C++ for returning multiple values from a method or function.)
We have a
getSanitized()
method forUser
objects that produces a JSON object appropriate to show members, hiding certain fields like those related to soft deletion. Also, we'll commonly want topopulate()
our model schema "foreign key"-like references before sending them as API request results.There's already a standardized concept in software development, for an object for this purpose: a "data transfer object," or "DTO," which is distinct from a "model" schema object.
The basic idea behind a DTO is that it's just "dumb," first of all: it lacks all model object extension logic. (Secondly, a DTO is serializable, though this likely isn't a difficult concern for us to satisfy with any JSON objects we're likely to produce.)
Any time we pass back a model object from the API, we basically call an equivalent to the
User
model/servicegetSantized()
method to produce a DTO. Further, we should standardize these DTOs, in their own folder.Whichever of us get to it first, @vprusso, we can produce a folder of
userDto
,submissionDto
, etc., and these will be the result ofgetSantized()
(orgetDto()
) service methods.We don't necessarily need a DTO for every model, but we should have one for every model we return as an API call result.