Serialized Entities displaying only ID - symfony

I'm using JMSSerializer and FOSRestBundle. I have a fairly typical object graph, including some recursion.
What I would like to accomplish is that included objects beyond a certain depth or in general are listed only with their ID, but when serialized directly, with all data.
So, for example:
Users => Groups => Users
when requesting /user/1 the result should be something like
{ "id": 1, "name": "John Doe", "groups": [ { "id": 10 }, { "id": 11 } ] }
While when I request /group/10 it would be:
{ "id": 10, "name": "Groupies", "users": [ { "id": 1 }, { "id": 2 }, { "id": 4 } ] }
With #MaxDeph I can hide the included arrays completely, so I get
{ "id": 1, "name": "John Doe", "groups": [] }
But I would like to include just the IDs so that the REST client can fetch them if it needs them, or consult his cache, or do whatever.
I know I can manually cobble this together using groups, but for consistency reasons I was wondering if I can somehow enable this behaviour in my entire application, maybe even with a reference to maxdepth so I can control where to include IDs and where to include full objects?

For the sake of those finding this:
I found no other solution, but doing this with groups works just fine and gives me the result I was looking for.

Related

How to handle Polymorphic endpoints on Pact?

I have an app where I can search for Books and Movies. These 2 entities have different properties, so their JSON structures are different.
I also have a GET /favorites endpoint which should return both Books and Movies.
GET /favorites
{
"favorites": [
{
"type": "book",
"title": "Foo",
"author": "John"
},
{
"type": "movie",
"name": "Bar",
"producers": [
{
"firstName": "Mary"
}
]
}
]
}
I searched for for docs on this case but I can't find anything. How can I write a Pact contract for this use case?
I would write two separate test cases for this, and use Provider States to differentiate the two payloads.
For example:
When there are books
When there are movies
Or something to that effect. See [1] for related background on this.
[1] https://docs.pact.io/faq#why-is-there-no-support-for-specifying-optional-attributes

Firestore Security Rules Really Spaghetti-Like?

while working on Firestore Security rules, I found out that there is no way to specify read/write-access on a Field-Level.
Everything that can be done is to specify access on a Document/Collection level.
But doesn't this enforce really weird database structures?
Consider this example:
[
{
"id": 15,
"name": "room1",
"color": "red",
"owner": "Tim"
},
{
"id": 642,
"name": "room2",
"color": "green",
"owner": "Charles"
},
{
"id": 989,
"name": "room3",
"color": "blue",
"owner": "Jane"
}
]
In this example I want to make it possible for e.g. Jane to read the Fields id name and owner of every entry in the collection, but I don't want her to see the field color of the rooms of the other persons.
This would be of course be possible with a data structure like this:
[
{
"id": 15,
"name": "room1",
"owner": "Tim",
"private_values": {
"color": "red"
}
},
{
"id": 642,
"name": "room2",
"private_values": {
"color": "green"
},
"owner": "Charles"
},
{
"id": 989,
"name": "room3",
"private_values": {
"color": "blue"
},
"owner": "Jane"
}
]
Everything I did was just move the "private"-values (in this case only the color) into another extra collection.
This way I can just set a rule for the root-object, and another extra rule on the object private_values.
Even though this is entirely possible to do, I wouldn't consider it especially clean when extrapolated to a bigger example where there would be for example more groups of users, who all need to be able to see different fields.
Is there a cleaner and better way to do this than the one I just explained, or is there anything else I missed?
Regards
You didn't miss anything. This is exactly what you're supposed to do. Documents in Firestore are the most granular unit for operations.
Note that you can also not read a partial document (you must read all the fields if you want to read any of the fields). If you write a Cloud Function that triggers when a document changes, you always receive the contents of the entire document, and you can't write a trigger for when an individual field changes.

FHIR : adding a custom extension

I would like to add to add a custom extension to my Schedule resource.
In my app, Schedule have visit motives (reasons). I know there's a list of classified appointments / encounter reasons but I would like to use mine.
I have something like this :
{
"resourceType":"Schedule",
"identifier":"logical_id",
"type":"schedule_speciality",
"actor":{
"practioner_id":"identifier",
"practioner_name":"practioner name"
},
"external_id":{
"extension":[
{
"url":"http://api.test.com/fhir/schedule/external_id",
"valueIdentifier":"external_id"
}
]
},
"visit_motives":{
"extension":[
{
"url":"https://api.test.com/fhir/ValueSet/schedule#visit_motives",
"valueString":"vist_motive1"
},
{
"url":"https://api.test.com/fhir/ValueSet/schedule#visit_motives",
"valueString":"vist_motive2"
},
{
"url":"https://api.test.com/fhir/ValueSet/schedule#visit_motives",
"valueString":"vist_motive3"
}
]
},
"practice_id":{
"extension":[
{
"url":"https://api.test.com/fhir/schedule/practice_id",
"valueIdentifier":"practice_id"
}
]
}
}
I'm not sure about this part :
"visit_motives":{
"extension":[
{
"url":"https://api.test.com/fhir/ValueSet/schedule#visit_motives",
"valueString":"vist_motive1"
},
{
"url":"https://api.test.com/fhir/ValueSet/schedule#visit_motives",
"valueString":"vist_motive2"
},
{
"url":"https://api.test.com/fhir/ValueSet/schedule#visit_motives",
"valueString":"vist_motive3"
}
]
}
Is it correct to add an extension this way ? There are always multiple visit motives for a specific schedule so I have to list them.
I also have seen this kind of things :
"visit_motives": {
"coding": [
{
"system": "https://api.test.com/fhir/ValueSet/schedule#visit_motives",
"code": "visit_motive1"
}
]
}
Which one is the correct one or am I wrong ?
There are several issues here:
It seems odd to capture a "reason" on a schedule. A schedule says when a particular clinician or clinic or other resource is available. E.g. "Dr. Smith takes appointments Mon/Wed/Fri from 1pm-4pm". So if you were to capture a reason on the resource, it would reflect "Why does Dr. Smith have a schedule?" Typically reasons are captured for an individual Appointment. That's the resource that reserves a particular slot for a planned visit. And Appointment already has an element for reason where you're free to use your own codes or just send text.
You have extensions to convey identifiers, but Schedule already has an element for identifiers. Why would you use extensions instead of the standard element? Note that you can use the "system" and/or "type" components to differentiate different kinds of identifiers.
You're sending "identifier", "type", "name", etc. as simple strings - but they're complex data types, so you need to communicate the child elements
actor is of type Reference - that means you need to point to the Practitioner resource. You can't send the properties in-line. (If the Practitioner only exists in the context of the Schedule, you could use the "contained" approach which would use an internal reference, but containment doesn't seem to make sense in this use-case.
The URL for your extension contains ValueSet, which isn't correct - extensions are all structure definitions. Also, there shouldn't be a # symbol in the URL.
Your syntax for extensions is incorrect. You can't introduce new properties in FHIR. The property name for all extensions is just "extension". You differentiate by the URL. So your syntax should be:
{
"resourceType":"Schedule",
"id":"logical_id",
"extension": [
{
"url":"https://api.test.com/fhir/StructureDefinition/schedule-visit_motive",
"valueString":"vist_motive1"
},
{
"url":"https://api.test.com/fhir/StructureDefinition/schedule-visit_motive",
"valueString":"vist_motive2"
},
{
"url":"https://api.test.com/fhir/StructureDefinition/schedule-visit_motives",
"valueString":"vist_motive3"
}
],
"identifier": [
{
"system": http://api.test.com/fhir/NamingSystem/external_id",
"value": "external_id"
}
{
"system": http://api.test.com/fhir/NamingSystem/practice_id",
"value": "practice_id"
}
]
"type": {
"coding": {
"system": "http://somewhere.org/fhir/CodeSystem/specialties",
"code": "schedule_speciality"
},
"text": "Some text description of specialty"
},
"actor":{
"reference": "http://myserver.org/fhir/Practitioner/12345"
"display": "Dr. smith"
}
}

ImmutableJS how to simplify a filter and update logic

The following is my structure of data
[
{
"id": 1,
"title": "Welcome to my playground",
"description": "This is so fun to play with, you will like it <3",
"comments": [
{
"id": 1140406,
"comment": "this is an example comment",
"postId": 1
}
]
},
...
]
And I'm trying to use immutable js to do this operation
Get all the posts
Search for a post I want to add comment to
Adding the comments when the post is found
The following is my code
posts = posts.map((post) => {
if(post.get('id') == payload.post_id) {
return post.update('comments', (comments) => {
return comments.push(Map({
id: payload.id,
comment: payload.comment
}));
});
}
return post;
});
But I assume this pattern is very common and there should be a simpler way to do this in immutableJS. Any advice will be helpful, thanks.
First off, it's worth mentioning that your Data structure is Immutable Lists and Maps.. not JS Arrays and Objects.
OK, without changing your data structure you could do:
posts.map(post => post.get('id') === payload.post_id ?
post.update('comments', comments.push(payload) :
post)
If you were to change your data structure, and instead of having a List of posts, had a Map of post's with their ID as the key you could just do:
post.updateIn([payload.post_id, 'comments'], comments => comments.push(payload))
BTW you can use push or concat here, both will function the same.
Also, if comments may be undefined, you can provide a "noSetValue" as a List (https://facebook.github.io/immutable-js/docs/#/List/updateIn):
posts.map(post => post.get('id') === payload.post_id ?
post.update('comments', Immutable.List([]), comments.push(payload) :
post)
post.updateIn([payload.post_id, 'comments'], Immutable.List([]), comments => comments.push(payload))
For others who has the same question: One should consider a data normalisation (search for normalizr). You could then normalise your data to something like:
"entities": {
"posts": {
"1": {
"id": 1,
"title": "Welcome to my playground",
"description": "This is so fun to play with, you will like it <3",
"comments": [1140406, 1140407, 1140408]
},
"42" : {...}
}
"comments": {
"1140406": {
"id": 1140406,
"comment": "this is an example comment",
"postId": 1
},
"1140407": {...}
}
}
then updating post and comments becomes much easier

How can I retrieve multiple objects by key?

I was just looking in the docs but couldn't find anything.
So my web app has a structure that's similar to the one in this site.
For the sake of simplicity, let's say my app has only questions which are catalogued by tags. As suggested in the docs, we store our data with a flat, non-normalized structure (E.g.
{
"questions": {
...
},
"tags": {
"tag1": {
"name": "Tag1",
"questions": { "0": true, "1": true }
},
"tag2": {
"name": "Tag2",
"questions": { "2": true, "3": true }
}
}
}
), rather than a normalized structure without data replication like:
{
"questions": {
"0": { "title": ..., "tag": ... },
"1": { "title": ..., "tag": ... },  
}
}
One of the advantages of using the first structure is that I can search for questions that have a certain tag without downloading all the data of all of the questions first: querying for /tags/tag1/questions, will return all the object with all of the question's keys. Now, I can query for the questions, but how do I do that?
I don't want to make ten requests for every question, it seems a waste of time and performance, but I couldn't find a way to make Firebase filter by multiple keys. It seems I can only give Firebase one input at a time. I think (and I hope) I am missing something here. What is it?
If I really can't do this, how do I search by tags here?

Resources