how to GET a Bundle of FHIR that contains both, the Paient details and the Claims he/she has taken? - hl7-fhir

If I have a patient ../Patient/f8d8477c-1ef4-4878-abed-51e514bfd91f,
and a claim ../Claim/<id> which has a reference to the above patient:
"patient": {
"reference": "f8d8477c-1ef4-4878-abed-51e514bfd91f",
"display": "John_Smith"
}
How do i query FHIR to get a bundle that has the Patient and its associated Claims ?
Do i need to add a # in the reference value ?

You could either search for the Patient and _revinclude the Claims, or search for the Claims and _include the Patient. I recommend the latter because it allows for pagination if there happen to be a large number of claims - you want the primary results to be what you're paging through, not the include/revinclude.
Patient?_id=f8d8477c-1ef4-4878-abed-51e514bfd91f&_revinclude=Claim:patient
Claim?patient=Patient/f8d8477c-1ef4-4878-abed-51e514bfd91f&_include=Claim:patient

Related

Apollo Gateway: duplicate / identical types across subgraphs returns null results?

My team and I are trying to move away from our monolithic Apollo Server API pattern toward GQL micro services with Apollo Federation.
Before we get into any code, some preface: my team has used GraphQL Codegen for our monolith to make a single master schema by finding and combining all the various type defs scattered across any number of .graphql files. The resulting output is a src/generated/types.ts file, which several of our resolvers and utility functions import the generated types from. This of course won't work if we're looking to deploy our micro services in isolation.
So, moving towards using a gateway, and with the current goal of being able to continue using GraphQL Codegen to generate and import types, we've simply got some type defs duplicated for now in order to do local type generation. Any optimizations and deduping will occur when we get the time, or by necessity if that isn't something we can have as tech debt. 😬
Minus some redacted information for security purposes, this same file is duplicated across all subgraphs which the gateway consumes.
users.graphql
extend type Query {
self: User
}
type User implements IDocument & ICreated & IUpdated & IDisplayName {
"Unique identifier for the resource across all collections"
_id: ID
"Unique identifier for the resource within its collection"
_key: ID
"Unique identifier for revision"
_rev: String
"ISO date time string for the time this resource was created"
createdAt: String
"Unique identifier for users that created this resource"
createdBy: ID
"ISO date time string for the time this resource was created"
updatedAt: String
"Unique identifier for users that created this resource"
updatedBy: ID
"A preformatted name safe to display in any HTML context"
displayName: String
"Email addresses"
email: String
"Determines if a users is a service account supporting applications"
isServiceAccount: Boolean
}
extend type Mutation {
user: UserMutation
}
type UserMutation {
save(user: UserInput): User
}
input UserInput {
"Unique identifier for the resource across all collections"
_id: ID
"Unique identifier for the resource within its collection"
_key: ID
"Unique identifier for revision"
_rev: String
"A preformatted name safe to display in any HTML context"
displayName: String
"Email addresses"
email: String
}
GraphQL Codegen generates types as expected, and the service compiles just fine. What's more is that the Gateway also seems to have no problems (i.e. compiles and runs) in stitching together several subgraphs containing the duplicate types.
However, when I attempt to execute the following query on GraphQL Playground,
query Self {
self {
_id
_key
displayName
email
}
}
It just returns
{
"data": {
"self": null
}
}
If I change the Gateway's supergraphSdl to only grab just one micro service, thus avoiding type duplication, I get results as expected:
{
"data": {
"self": {
"_id": "users/c3a6062f-b070-4e39-8b2a-9d1354e9dccb",
"_key": "c3a6062f-b070-4e39-8b2a-9d1354e9dccb",
"displayName": "redacted",
"email": "redacted"
}
}
}
(Here's the resolver if it matters. I've debugged the dickens out of it and have come to the conclusion that it works fine.)
const query: QueryResolvers = {
self: (_, __, context) => context.user,
};
I'm still pretty new to Federation, so I apologize if there's an obvious answer. But given what I've related, is there any way to
allow type duplication across the several subgraphs to be stitched together, and is there a way to
still keep isolated, generated types for each service?
I've looked at various possible ways to resolve this issue
, exploring the extends keyword and wondering if extending the User type def across all but one of the services would leave just one "master" User type def: that either didn't work or I did something wrong. I've only got the vaguest idea of what's going on, and I'm guessing the Gateway is confused about which type and from which service it's supposed to use in order to return a response.
Here are various relevant packages and versions which might help solve the issue:
Gateway
"#apollo/gateway": "^2.0.1",
"graphql": "^16.4.0"
GQL Micro services
"graphql": "^16.4.0"
"#graphql-codegen/cli": "^2.6.2",
"#apollo/federation": "^0.36.1",
Any help is immensely appreciated, even if it means what I want isn't possible! If more information and / or code is required I will be happy to give it.
I didn't solve the quest for allowing duplication, but ultimately, I didn't want to have to do it anyway, and since I don't think I even can now, that's fine.
Instead, I was able to find a much more elegant solution!
We just have to point GraphQL Codegen's schema field in the various codegen.yml files to whichever .graphql sources are required. That way, we get the types we need to use, and we prevent usurpation of single sources of truth by not redeclaring type defs. So, happy ending. 🥳
Great discussion y'all

Graphql type with id property that can have different values for same id

I was wondering if an object type that has an id property has to have the same content given the same id. At the moment the same id can have different content.
The following query:
const query = gql`
query products(
$priceSelector: PriceSelectorInput!
) {
productProjectionSearch(
priceSelector: $priceSelector
) {
total
results {
masterVariant {
# If you do the following it will work
# anythingButId: id
id
scopedPrice {
country
}
}
}
}
}
`;
If the PriceSelectorInput is {currency: "USD", country: "US"} then the result is:
{
"productProjectionSearch": {
"total": 2702,
"results": [
{
"name": "Sweater Pinko white",
"masterVariant": {
"id": 1,
"scopedPrice": {
"country": "US",
"__typename": "ScopedPrice"
},
"__typename": "ProductSearchVariant"
},
"__typename": "ProductProjection"
}
],
"__typename": "ProductProjectionSearchResult"
}
}
If the PriceSelectorInput is {currency: "EUR", country: "DE"} then the result is:
{
"productProjectionSearch": {
"total": 2702,
"results": [
{
"name": "Sweater Pinko white",
"masterVariant": {
"id": 1,
"scopedPrice": {
"country": "DE",
"__typename": "ScopedPrice"
},
"__typename": "ProductSearchVariant"
},
"__typename": "ProductProjection"
}
],
"__typename": "ProductProjectionSearchResult"
}
}
My question is that masterVariant of type ProductSearchVariant has id of 1 in both cases but different values for scopedPrice. This breaks apollo cache defaultDataIdFromObject function as demonstrated in this repo. My question is; is this a bug in apollo or would this be a violation of a graphql standard in the type definition of ProductSearchVariant?
TLDR
No it does not break the spec. The spec forces absolutely nothing in regards caching.
Literature for people that may be interested
From the end of the overview section
Because of these principles [... one] can quickly become productive without reading extensive documentation and with little or no formal training. To enable that experience, there must be those that build those servers and tools.
The following formal specification serves as a reference for those builders. It describes the language and its grammar, the type system and the introspection system used to query it, and the execution and validation engines with the algorithms to power them. The goal of this specification is to provide a foundation and framework for an ecosystem of GraphQL tools, client libraries, and server implementations -- spanning both organizations and platforms -- that has yet to be built. We look forward to working with the community in order to do that.
As we just saw the spec says nothing about caching or implementation details, that's left out to the community. The rest of the paper proceeds to give details on how the type-system, the language, requests and responses should be handled.
Also note that the document does not mention which underlying protocol is being used (although commonly it's HTTP). You could effectively run GraphQL communication over a USB device or over infra-red light.
We hosted an interesting talk at our tech conferences which you might find interesting. Here's a link:
GraphQL Anywhere - Our Journey With GraphQL Mesh & Schema Stitching • Uri Goldshtein • GOTO 2021
If we "Ctrl+F" ourselves to look for things as "Cache" or "ID" we can find the following section which I think would help get to a conclusion here:
ID
The ID scalar type represents a unique identifier, often used to refetch an object or as the key for a cache. The ID type is serialized in the same way as a String; however, it is not intended to be human‐readable. While it is often numeric, it should always serialize as a String.
Result Coercion
GraphQL is agnostic to ID format, and serializes to string to ensure consistency across many formats ID could represent, from small auto‐increment numbers, to large 128‐bit random numbers, to base64 encoded values, or string values of a format like GUID.
GraphQL servers should coerce as appropriate given the ID formats they expect. When coercion is not possible they must raise a field error.
Input Coercion
When expected as an input type, any string (such as "4") or integer (such as 4) input value should be coerced to ID as appropriate for the ID formats a given GraphQL server expects. Any other input value, including float input values (such as 4.0), must raise a query error indicating an incorrect type.
It mentions that such field it is commonly used as a cache key (and that's the default cache key for the Apollo collection of GraphQL implementations) but it doesn't tell us anything about "consistency of the returned data".
Here's the link for the full specification document for GraphQL
Warning! Opinionated - My take on ID's
Of course all I am about to say has nothing to do with the GraphQL specification
Sometimes an ID is not enough of a piece of information to decide whether to cache something. Let's think about user searches:
If I have a FavouriteSearch entity that has an ID on my database and a field called textSearch. I'd commonly like to expose a property results: [Result!]! on my GraphQL specification referencing all the results that this specific text search yielded.
These results are very likely to be different from the moment I make the search or five minutes later when I revisit my favourite search. (Thinking about a text-search on a platform such as TikTok where users may massively upload content).
So based on this definition of the entity FavouriteSearch it makes sense that the caching behavior is rather unexpected.
If we think of the problem from a different angle we might want a SearchResults entity which could have an ID and a timestamp and have a join-table where we reference all those posts that were related to the initial text-search and in that case it would make sense to return a consistent content for the property results on our GraphQL schema.
Thing is that it depends on how we define our entities and it's ultimately not related to the GraphQL spec
A solution for your problem
You can specify how Apollo generates the key for later use as key on the cache as #Matt already pointed in the comments. You may want to tap into that and override that behavior for those entitites that have a __type equal to your masterVariant property type and return NO_KEY for all of them (or similar) in order to avoid caching from your ApolloClient on those specific fields.
I hope this was helpful!

Google Places Nearby search results - missing detail Data?

I'm currently working on a project in which we perform "Nearby" queries for places using keywords, and then we make follow-up "Detail" requests to obtain more information about specific places of interest.
With Google's new pricing model in the works, the documentation warns about the cost of the Nearby search, but the warning seems to imply that the follow-up detail request will no longer be necessary because our original search should give us everything we need:
By default, when a user selects a place, Nearby Search returns all of
the available data fields for the selected place, and you will be
billed accordingly. There is no way to constrain Nearby Search
requests to only return specific fields. To keep from requesting (and
paying for) data that you don't need, use a Find Place request
instead.
However, I'm not seeing this. When I run a sample request, the results from my Nearby request contains only minimal data related to the places Google finds. To get details, I still have to do a follow-up detail request.
Does anyone know if there's something I may be overlooking? I'm including my request URL (sans API key).
https://maps.googleapis.com/maps/api/place/nearbysearch/json?key=xxxxxxxxxx&location=30.7329,-88.081987&radius=5000&keyword=insurance
And this is an example of one of the results I received:
{
"geometry": {
"location": {
"lat": 30.69254,
"lng": -88.0443999
},
"viewport": {
"northeast": {
"lat": 30.69387672989272,
"lng": -88.04309162010728
},
"southwest": {
"lat": 30.69117707010728,
"lng": -88.04579127989273
}
}
},
"icon": "https://maps.gstatic.com/mapfiles/place_api/icons/generic_business-71.png",
"id": "53744cdc03f8a9726593a767424b14f7f8f86049",
"name": "Ann M Hartwell - Aflac Insurance Agent",
"place_id": "ChIJj29KxNZPmogRJovoXjMDpQI",
"plus_code": {
"compound_code": "MXV4+26 Mobile, Alabama",
"global_code": "862HMXV4+26"
},
"reference": "CmRbAAAAcHM1P7KgNiZgVOm1pWojLto9Bqx96h2BkA-IyfN5oAz1-OICsRXiZOgwmwHb-eX7z679eFjpzPzey0brgect1UMsAiyawKpb5NLlgr_Pk8wBJpagRcKQF1VSvEm7Nq6CEhCfR0pM5wiiwpqAE1eE6eCRGhQPJfQWcWllOVQ5e1yVpZYbCsD01w",
"scope": "GOOGLE",
"types": [
"insurance_agency",
"point_of_interest",
"establishment"
],
"vicinity": "70 N Joachim St, Mobile"
}
I thought about deleting this question, but I guess I'll leave it up in case anyone else is confused like I was.
It turns out the extra detail fields I was looking for in the Nearby Search results were there...sort of.
Google's new pricing model categorizes place data fields into three tiers: Basic, Contact, and Atmosphere (Basic data is free, but the other two add to the cost).
As part of these changes, Place API calls have been expanded to allow users to specify the data fields they want so that they don't have to pay for that extra data if they don't need it.
The Nearby Search query, as per the note in the question, includes all the data fields available, and doesn't support a parameter for controlling the data -- it's always going return data that falls into the [Basic + Contact + Atmosphere] bucket.
So far, that's all well and good.
Where things became confusing to me, though, is the specifics of what is included in the different data tiers. I skimmed through these notes several times before I noticed the contents were different.
This is how the fields break down with the Places details request:
Basic
The Basic category includes the following fields: address_component,
adr_address, alt_id, formatted_address, geometry, icon, id, name,
permanently_closed, photo, place_id, plus_code, scope, type, url,
utc_offset, vicinity
Contact
The Contact category includes the following fields:
formatted_phone_number, international_phone_number, opening_hours,
website
Atmosphere
The Atmosphere category includes the following fields: price_level,
rating, review
And this is how it looks for the Places search request:
Basic
The Basic category includes the following fields: formatted_address,
geometry, icon, id, name, permanently_closed, photos, place_id,
plus_code, scope, types
Contact
The Contact category includes the following field: opening_hours
(Place Search returns only open_now; use a Place Details request to
get the full opening_hours results). Atmosphere
The Atmosphere category includes the following fields: price_level,
rating
I haven't found documentation for it, specifically, but the results from a Nearby Search request seems close (but not identical) to the Place search (including Contact and Atmosphere).
I had originally thought the fact that Nearby Search results now include Contact and Atmosphere data (when available), that meant it would contain all the fields itemized as Contact and Atmosphere data in the Place details documentation, but that's not the case.

Spring Data MongoDB - Embedded Document as Reference in Other Document

I'd like to know if it's possible (or even correct) to use embedded documents as reference in other documents.
I know I can move the embedded document to its own collection but the main goal is to have the performance benefit of embedded document and also avoid duplication.
For example:
User
{
_id: ObjectId("4fed0591d17011868cf9c982"),
_class: "User"
...
addresses: [ {
_id: ObjectId("87KJbk87gjgjjygREewakj86"),
_class: "Address",
...
} ]
}
Order
{
_id: ObjectId("gdh60591d123487658cf9c982"),
_class: "Order",
...
address: ObjectId("87KJbk87gjgjjygREewakj86")
}
Your case reminds me of the typical relational approach, which I was a victim of, too, when starting to use document-oriented DBs. All of your
entities in the example are referenced, there is no redundancy anymore.
You should start to get used to the idea of letting go normalization and starting to duplicate data. In many cases it is hard to determine which data should be referenced and which should be embedded. Your case tends to be quite clear, though.
Without knowing your entire domain model, the address seems to be a perfect candidate for a value object. Do not maintain an Address collection, embed it within the user object. In Order, you could either make a reference to the user, which gives you implicitly the address object and might make sense, since an order is made by a user.
But...I recommend that you embed the address entirely in the Order. First, it is faster since you don't need to resolve a reference. Second, the address in shipped orders should never change! Consider orders of the last year. If you hold a reference to the address you would lose the information to which address they were shipped, once the user changes his address.
Suggestion: Always take a snapshot of the address and embed it in the Order. Save the MongoDB ID of the user as a regular string (no #DBRef) within the `Order. If a user should change his address, you can make a query for all non-shipped orders of that user and amend the address.
Since you asked if this is even correct, I would say, gently, "No." At least not typically.
But if you did want to insist on using an embedded address from user:
You can reference the user embedded address in the Order object, just not the way you might think! If you stored the id of the user in the order (it should already be there if Order belongs_to User), then you merely use user.address instead of copying the address instance as you have done.
ALTERNATIVE
I hope to illustrate a better approach to modeling the domain...
A more common approach is to instantiate a new order object, using the user's address as the default "ship to" address for the order, yet allow the user to override the shipping address if desired. In theory, each order could have a different "ship to" address.
Just because two classes have an address, does not mean they are necessarily the same address.
COMMENTARY
Orders are more of an historical document, versus one that changes. Therefore, Orders are generally immutable once placed, your model allows the address to change every time the user changes their address. That change ripples into the Orders, and would be incorrect insofar as normal order business logic goes.
Assume your address last year was in Spain and you had Order #1 show Spain when you ran a report of Orders last year. Imagine if your address this year is now Portugal and Order #1 now shows Portugal in the same report. That would be factually incorrect.
BTW: #Matt gave you the tip that from a "problem domain" perspective, you likely do not want to model it as you have. I am merely elaborating on that...
Since I got no answer I will post here how I did it. If you have a better solution I am happy to here it.
It looks like there's no way to create/reference a collection inside another collection, so I had to extract the addresses from the user collection to it's own collection and create a reference in the User and Order collections as mentioned here. I was expecting something more flexible, but couldn't find one.
User
{
_id: ObjectId("4fed0591d17011868cf9c982"),
_class: "User"
...
addresses: [ {
"$ref" : "addresses",
"$id" : ObjectId("87KJbk87gjgjjygREewakj86")
} ]
}
Address
{
_id: ObjectId("87KJbk87gjgjjygREewakj86"),
...
}
Order
{
_id: ObjectId("gdh60591d123487658cf9c9867"),
_class: "Order",
...
address: {
"$ref" : "addresses",
"$id" : ObjectId("87KJbk87gjgjjygREewakj86")
}
}

How to determine if a signed in user is a teacher in google classroom?

For the app I am building for elementary schools, teachers can access it by logging into their classroom account, but students cannot. How do I determine if a particular user is a teacher?
I noticed that the test teacher account has the permission CREATE_COURSE, but the student does not. Can I assume that is universally true... that if someone has a CREATE_COURSE permission, they are a teacher for some course.
As you mentioned above, if you send request to userProfiles, with userId, if in the response you get permissions as create_course, then its teacher. Other wise its student.
{
"id": string,
"name": {
object(Name)
},
"emailAddress": string,
"photoUrl": string,
"permissions": [
{
object(GlobalPermission)// Here it should be create_course for teacher
}
],
}
A slightly different approach here is list courses with the query parameter: 'teacherId' => 'me'. That way you get all the courses the current user is teaching. If you get 0 results, it means the user is not a teacher anywhere. Anyway, if you just need to know if the user is considered a teacher, it might be more efficient the other way around.
Distinguishing teachers from students via the CREATE_COURSE permission may be sufficient for your use case, but note that depending on how the domain's instance of Classroom has been configured, users may be able to self-identify as teachers; see https://support.google.com/edu/classroom/answer/6071551.
Just recently, according to https://issuetracker.google.com/issues/36760055, you may use https://developers.google.com/classroom/reference/rest/v1/userProfiles to determine whether the user is teacher
{
"verifiedTeacher": boolean
}

Resources