Here's a little bit of language-extension-design style fun.
DACTAL brings API-mediated data into its query-space with adapters, which encapsulate an API interaction into a named virtual property. So, e.g., Apple Music offers an endpoint to go from an artist ID to that artist's similar artists. My generalized style for adapters has been to name them in source targets form, so this one would be artist similar artists. Adapters return results like this:
but I always use a data-specific property-name instead of "data", like, in this case:
So a query to go from all my artists to all their similar artists would be:
But in cases where the adapter is just looking up things by ID, and the resulting objects thus have those IDs themselves, it is not necessary to return intermediate objects. That is, an adapter to look up playlists by ID, if it followed the above pattern, would be id playlists, and would return
and would thus require
but since each ID leads to one playlist, which has that ID already, the adapter can just return the playlists themselves, allowing the query to be just
Note that adapters can take IDs as strings, or objects that have ID properties, so it is not necessary to have separate id playlists and stub playlists, and this makes it even more natural to call the adapter playlists.
Now, in my experimental Apple Music data-explorer I also need an adapter to get the user's list of playlists. In the abstract this should be user playlists, but in a bit of dubious cleverness I decided to make the playlists adapter also recognize the special ID "me" and return the list of the current user's playlists. This comes back as a list of playlist stubs, without tracks, like
but you can get the full playlists by just sending those results back through the same adapter again. So the full query ends up being:
instead of, had I been strict about consistency:
or, had I been maximally strict and maximally generic:
I'm not completely confident that I like the specific decisions I made for this case, and if AM allowed us to get user playlists for any user other than the current one, I would definitely have separated user playlists from playlists. But I'm pretty confident that it's good that the domain curator, rather than the language designer, gets to make these decisions, and thus all three of these variants are available to you according to your tastes.
DACTAL brings API-mediated data into its query-space with adapters, which encapsulate an API interaction into a named virtual property. So, e.g., Apple Music offers an endpoint to go from an artist ID to that artist's similar artists. My generalized style for adapters has been to name them in source targets form, so this one would be artist similar artists. Adapters return results like this:
{id: whatever, data: [...]}
but I always use a data-specific property-name instead of "data", like, in this case:
{id: whatever, 'similar artists': [...]}
So a query to go from all my artists to all their similar artists would be:
artists.artist similar artists.similar artists
But in cases where the adapter is just looking up things by ID, and the resulting objects thus have those IDs themselves, it is not necessary to return intermediate objects. That is, an adapter to look up playlists by ID, if it followed the above pattern, would be id playlists, and would return
{id: whatever, playlists: [{...}]}
and would thus require
playlistids.id playlists.playlists
but since each ID leads to one playlist, which has that ID already, the adapter can just return the playlists themselves, allowing the query to be just
playlistids.playlists
Note that adapters can take IDs as strings, or objects that have ID properties, so it is not necessary to have separate id playlists and stub playlists, and this makes it even more natural to call the adapter playlists.
Now, in my experimental Apple Music data-explorer I also need an adapter to get the user's list of playlists. In the abstract this should be user playlists, but in a bit of dubious cleverness I decided to make the playlists adapter also recognize the special ID "me" and return the list of the current user's playlists. This comes back as a list of playlist stubs, without tracks, like
{id: "me", playlists: [{id: "p1", name: "Playlist 1"}, ...]}
but you can get the full playlists by just sending those results back through the same adapter again. So the full query ends up being:
me.playlists.playlists.playlists
instead of, had I been strict about consistency:
me.user playlists.playlists.id playlists.playlists
or, had I been maximally strict and maximally generic:
me.user playlists.data.id.id playlists.data
I'm not completely confident that I like the specific decisions I made for this case, and if AM allowed us to get user playlists for any user other than the current one, I would definitely have separated user playlists from playlists. But I'm pretty confident that it's good that the domain curator, rather than the language designer, gets to make these decisions, and thus all three of these variants are available to you according to your tastes.
