contentful / contentful.net

.NET Library for Contentful's Content Delivery and Management API
MIT License
95 stars 53 forks source link

Call to GetEntriesRaw not resolving linked entries like JavaScript Sdk #305

Closed paugrunge closed 9 months ago

paugrunge commented 1 year ago

Hi,

I need to obtain all entries from an environmet with same response as Javascript SDK, with fields object. "items": [ { "sys": {...}, "fields": {...}, }, ...... ]

When calling .NET SDK (contentful.aspnetcore version 7.2.2 and also contentful.csharp version 7.2.2) var entriesSdk = await _contenfulClient.GetEntries<dynamic>("?locale=*&include=10", default); the fields are missing and the item is flattened. I have read that "that’s part of what the SDK does to make serialization more logical when you use strongly typed objects." so the fields are not coming using dynamic type. Reference link where I read that: https://www.contentfulcommunity.com/t/how-can-i-get-the-items-from-getentries-as-jobjects-so-i-can-access-the-fields-and-metadata-as-json/674/4

So I went to the try a another method from SDK var entries = await _contenfulClient.GetEntriesRaw("?locale=*&include=10"); which responses with fields as curl. But the problem is that I am losing the levels of reference, even though I am asking highest level possible the response is as the include was not set when it comes to resolving links.

Then I tried calling by HttpClient directly var response = await _httpClient.GetStringAsync($"https://cdn.contentful.com/spaces/{spaceId}/environments/{environment}/entries?access_token={deliveryApiKey}&include=10&locale=*"); which again gets me the object I want with fields but is links are not resolved as using JavaScript Sdk.

I found JavaScript Sdk is using the contentful-resolve-response package, which converts the raw nodes into a rich tree of data.

What I expect for example in this content would be (is what I get from JavaScript SDK)


"customTexts":{
               "en":{

                  "sys":{...},
                  "fields":{
                     "contentId":{
                        "en":"text"
                     },
                     "landingTexts":{
                        "en":{
                           "signIn":"text"
                        },
                        "es":{
                           "signIn":"texto"
                        }
                     }
                  }
               }
            }

And what I get using GetEntriesRaw and HttpClient is this

 "customTexts": {
                    "en": {
                        "sys": {
                            "type": "Link",
                            "linkType": "Entry",
                            "id": "id"
                        }
                    }
                }

Is there a way with .NET SDK to have those links resolve? I am trying to avoid doing manually since is a very complex model with many entries linking to other entries.
I would appreciate any help addressing this. I am in need of same json response as Javascript Sdk (resolving links) because I am building a fallback in .NET to save contentful data as json in Azure Blob Storage, so in case of Contentful being down our FrontEnd can consume fallback and obtain same response.

Roblinde commented 1 year ago

@paugrunge the idea behind the GetEntriesRaw call is to not do any resolving, but to give you the raw response from the API. If you want to have the SDK resolve the links into strongly typed objects for you use the GetEntries method with a strong type instead (dynamic will not work as it does not have members to resolve to).

paugrunge commented 1 year ago

Thank you @Roblinde.

I have seen that GetEntries does resolve links when a strong type is used but I need to be agnostic of the type and content model being consumed, that is why the need of dynamic.

I have seen that when uisng GetEntries with a content type as query string even asking for dynamic the links are resolved, is that right for every link?

I am using

 var builder = new QueryBuilder<dynamic>().ContentTypeIs(contentType).LocaleIs(locale).Include(10).Limit(_pageSize).Skip(skip);
        var entriesByContentType = await _contenfulClient.GetEntries(builder);
paugrunge commented 1 year ago

Hi @Roblinde

Using this approach of getting entries dynamic and sending contentType (content types are asked to GetContentTypes because like I said we need to be agnostic of any content model that could came) I have seen that the links are resolved but only if that linked child has one relation.

For example we have an institutionContent model that has an institutionLogo inside, both are entries. If I create ins1 that has linked logo1 the links are resolved. But if i have ins1 and ins2 linked to logo1, I only got links resolved in one of them, and the other only has the reference.

Why this changed if I asking for entries of contentType institutionContent and one has links of type institutionLogo resolved and the other one does not?

Roblinde commented 1 year ago

Hi @paugrunge If you need to be agnostic of the type I would suggest using a ContentTypeResolver: https://www.contentful.com/developers/docs/net/tutorials/using-net-cda-sdk/#get-entries-of-multiple-types-or-by-interface

You can also have a read here for a better understanding of the deserialization process: https://robertlinde.se/posts/why-is-my-item-null-contentful-net/