I want to update parent relationships for specified entity. The problem is when I query N:1 refs I get referencing attributes that is not always a single-valued navigation property. I do not know how can I distinguish is the attribute parentcustomerid referencing to an account or to a contact entity. So the question is: How can I properly get single-valued navigation property for my specified entity to be able update it using request to PATCH api/data/v9.0/contacts({id}) with the body:
{"single-valued navigation property#odata.bind" :
"/{accounts or contacts}({id})"}
When creating a HTTP Request, add Prefer: odata.include-annotations="*" to your HTTP Request Headers. This way the response not only will have a _[Field Name]_value field with the Id but also a _[Field Name]_value#Microsoft.Dynamics.CRM.lookuplogicalname with the logical name that you look for.
This is an example of a response for a request querying parentcustomerid of a specific contact without the header:
{
"#odata.context": "https://[Organization URI]/api/data/v9.0/$metadata#contacts(_parentcustomerid_value)",
"value": [
{
"_parentcustomerid_value": "bdeb86af-7e1c-e811-a837-000d3ac085f9",
"contactid": "b050f3bb-dbf7-e811-a98a-000d3ac02bae"
}
]
}
And this is an example of a response for the same request with the header added:
{
"#odata.context": "https://[Organization URI]/api/data/v9.0/$metadata#contacts(_parentcustomerid_value)",
"value": [
{
"_parentcustomerid_value#Microsoft.Dynamics.CRM.associatednavigationproperty": "parentcustomerid_account",
"_parentcustomerid_value#Microsoft.Dynamics.CRM.lookuplogicalname": "account",
"_parentcustomerid_value": "bdeb86af-7e1c-e811-a837-000d3ac085f9",
"contactid": "b050f3bb-dbf7-e811-a98a-000d3ac02bae"
}
]
}
Related
I'm working on a "global search" for my application.
Currently, I'm using hibernate-search to search for instances of multiple different objects and return them to the user.
The relevant code looks as follows:
Search.session(entityManager)
.search(ModelA.classs, ModelB.class)
.where(...)
.sort(...)
.fetch(skip, count);
Skip and count are calculated based on a Pageable and the result is used to create an instance of Page, which will be returned to the controller.
This works as I'd expect, however, the types generated by swagger-docs obviously doesn't know, what the type within the Page is, and therefore uses Object.
I'd like to expose the correct types, as I use them to generate the types for the frontend application.
I was able to set the type to an array, when overwriting the schema like this:
#ArraySchema(schema = #Schema(anyOf = {ModelA.class, ModelB.class}))
public Page<?> search(Pageable pageable) {
However, this just disregards the Page and also isn't correct.
The next thing I tried is extending the PageImpl, overwriting the getContent method, and specifying the same schema on this method, but this wasn't included in the output at all.
Next was implementing Page<T> myself (and later removing the implements reference to Page<T>) and specifying the same schema on getContent, iterator, and the field itself, but also to no effect.
How do I tell spring-docs, what the content of the resulting Page might be?
I stumbled upon this when trying to solve a similar problem
Inspired from this thread Springdoc with a generic return type i came up with the following solution, and it seems to apply to your case also. Code examples are in Kotlin.
I introduced a stub class that will just act as the Schema for the response:
private class PageModel(
#Schema(oneOf = [ModelA::class, ModelB::class]))
content: List<Object>
): PageImpl<Object>(content)
Then i annotated my Controller like this:
#Operation(
responses = [
ApiResponse(
responseCode = "200",
content = [Content(schema = Schema(implementation = PageModel::class))]
)
]
)
fun getPage(pageable: Pageable): Page<Object>
This generated this api response:
"PageModel": {
"properties": {
"content": {
"items": {
"oneOf": [
{
"$ref": "#/components/schemas/ModelA"
},
{
"$ref": "#/components/schemas/ModelB"
}
],
"type": "object"
},
"type": "array"
},
... -> more page stuff from spring's PageImpl<>
And in the "responses" section for the api call:
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PageModel"
}
}
},
"description": "OK"
}
All generated openapi doc is similar to the autogenerated json when returning a Page, it just rewrites the "content" array property to have a specific type.
My medication request resource contains a reference to Organization resource:
"requester": {
"agent": {
"reference": "Practitioner/12345",
"display": "Abhishek Nayyar"
},
"onBehalfOf": {
"reference": "Organization/56789",
"display": "XYZ Hospital"
}
},
I want to fetch this Organization Resource along with medication request resource using a single api call. I am doing this:
GET https://FhirServerBasePath/MedicationRequest?subject:Patient.identifier=1358&_include=MedicationRequest:requester:Organization
However, in the response, I am not getting organization resource. When I try to use the same query for Practitioner (which is also referenced under requester), I am able to fetch it successfully.
In STU3, the MedicationRequest requester search parameter only looks at MedicationRequest.requester.agent. There is no 'standard' search parameter that looks at MedicationRequest.requester.onBehalfOf, which means that unless the server supports a custom search parameter based on that element, there's no way to do an _include for it.
When i use get method on the below bright cove api to retrive video meta data, it generates json response with some fields.
"https://cms.api.brightcove.com/v1/accounts/510000340001/videos?sort=-updated_at&limit=1&offset=0"
How do we get additional tags which are not included, say for example 'category' field in the output json response?
I tried to append below in url and api does not detect.
?custom_field=category
If the video has a value set for that field, it will be present in the custom_fields object as below. If the field is empty, it will not be included for that video.
{
"name": "A video",
...
"custom_fields": {
"category": "something"
}
}
https://facebook.github.io/graphql/draft/#sec-Schema-Introspection
type __Schema {
types: [__Type!]!
queryType: __Type!
mutationType: __Type
subscriptionType: __Type
directives: [__Directive!]!
}
type __Type {
kind: __TypeKind!
name: String
description: String
...
Information downloaded from https://developer.github.com/v4/guides/intro-to-graphql/#discovering-the-graphql-api (curl -H "Authorization: bearer token" https://api.github.com/graphql)
(beginning of the file
{
"data": {
"__schema": {
"queryType": {
"name": "Query"
},
"mutationType": {
"name": "Mutation"
},
"subscriptionType": null,
"types": [
{
"kind": "SCALAR",
"name": "Boolean",
...
Question:
I interpreted this so this GitHub schema result is invalid because queryType doesn't specify a kind which is nonNullable (kind: __TypeKind!)
Is this result violating the schema rules or am I missing something?
This response passes validation because a missing field is not the same thing as a field that returns null. A field will be missing from the response only if it wasn't requested in the first place.
If you go to GitHub's GraphQL Explorer, you can generate an introspection query yourself, request the kind field as part of the selection set of the queryType field and it will return the field with a non-null value.
{
__schema {
queryType {
kind
}
}
}
Response:
{
"data": {
"__schema": {
"queryType": {
"kind": "OBJECT"
}
}
}
}
Fetching the schema by making a GET request to some endpoint is convenient, but it's not the standard way to introspect the schema. Instead, you should make the request using whatever selection set is needed against the endpoint itself. The drawback of doing it this less conventional way is made apparent by this question. In this case, whatever introspection query GitHub is making for you under the hood is missing one or more fields that could otherwise be requested. Because you're not the one making the introspection query, you don't know what to expect in terms of the shape of the response.
This sounds like a rookie question, but I'm wondering what's the best way to present paged resources with HAL format? Right now I'm using Spring HATEOAS API to convert Page object into resource PagedResourcesAssembler#toResource(Page<T>, ResourceAssembler<T,R>). This results in the following output:
{
"_links": {
"self": {
"href": "http://example.org/api/user?page=3"
},
…
}
"count": 3,
"total": 498,
"_embedded": {
"users": [
{
"_links": {
"self": {
"href": "http://example.org/api/user/mwop"
}
},
"id": "mwop",
"name": "Matthew Weier O'Phinney"
}
]
}
}
Everything works fine but the only problem is the collection being returned is under _embedded field and has the class name, so the client has to know this class name as well right? Would it be better to just return the collection under content like non-HAL format? If yes how should I achieve it using Spring HATEOAS?
That's not a problem, that's the way _embedded is defined in the HAL specification.
users is not a class, it's a link relation that will allow clients to actually find the collection it was asking for in the first place (e.g. using a JSONPath expression). That's not something coming out of the blue at all but usually is the same link relation, the client used to find that resource in the first place.
Assume an API root exposing this document:
{
"_links": {
"users": {
"href": "…"
},
…
}
}
Seeing that, the client would have to know the semantics of users to find the link it wants to follow. In your case users is basically pointing to a collection resource that supports pagination.
So if the client follows the link named users, it can then find the actual content it's looking for under _embedded.users in the HAL response by combining knowledge about the media type (HAL, _embedded) and the service's application-level semantics (users).