API-PLATFORM - model with object serialized to string at endpoint - symfony

I faced the problem with generating React components with api-platform-generate-crud.
Model has property that is object email.
I have serializer that make my email object a string.
API endpoint is serving string.
It works for GET & POST.
When I try to generate React components error message is
TypeError: Cannot read property '0' of undefined
Looking deeper into it, looks like that generator still see my email as object not a string.
Any idea how I can force API to 'see' email property as string not object ?

The data model you define is authoritative. Types in the Hydra documentation reflect the ones in PHP classes.
Here, the email property is of type object. If you set the related data as a string somewhere, you don't respect this contract anymore. The Hydra documentation is not in sync with the returned data.
You can change the type of the email property in the Hydra documentation by decorating the api_platform.hydra.normalizer.documentation service.
But I would recommend to keep the PHP classes' structure of your entities as close as possible of the structure exposed through the API.
Your classes should reflect the output of the API. You can use custom data providers to deal with more complex data structure (ex: ORM entities) before hydrating the structure to expose.

Related

Kotlin: Json: conflicting annotation schemes for name transcription

I read data from Firebase database into a Kotlin/Android program. The key names in Firebase are different from those of the corresponding Kotlin variables. I test this code with flat JSON files (for good reasons) where I retain the same key names used in Firebase, so I need to transcribe them too.
Firebase wants to annotate variables with #PropertyName; but Gson, which I use to read flat files, wants #SerializedName (which Firebase doesn't understand, unfortunately.)
Through trial and error I found that this happens to work:
#SerializedName("seq")
var id: Int? = null
#PropertyName("seq")
get
#PropertyName("seq")
set
Both Firebase and Gson do their thing and my class gets its data. Am I hanging by a thin thread here? Is there a better way to do this?
Thank you!,
You can probably solve this by using Kotlin's #JvmField to suppress generation of getters and setters. This should allow you to place the #PropertyName annotation directly on the property. You can then implement a Gson FieldNamingStrategy which checks if a #PropertyName annotation is present on the field and in that case uses its value; otherwise it could return the field name. The FieldNamingStrategy has to be set on a GsonBuilder which you then use to create the Gson instance.

API Platform custom IRI with value objects

I am currently trying to create a custom IRI for one of my entities in API Platform.
I know there is page in the documentation describing how to use a custom IRI (https://api-platform.com/docs/core/identifiers/), but I can't get it working.
My entity uses a value object for the id (currently used for IRI) and also for the name (should be used for IRI). But the values themself are priviate and scalar in the entity.
API Platform seems to get the information what should be used as the identifier, from my XML Doctrine mapping. I already tried to overwrite it by usung annotations, attributues and YAML definitions. Without luck.
The returned error reads:
preg_match(): Argument #2 ($subject) must be of type string
(at this point it receives the value object instead of the actual value)
best regards,
spigandromeda
I solved my problem.
To explain the solution, I have to dig a little into API Platform response generation.
API platform generates an IRI for every entity it returns (colelction and item operation)
it's using the Symfony router go generate the URI
all the necessary information can draw API Platform from different sources (YAML, XML, annotations, attributes)
the information include the identifier(s) defined for the entities resource
API Platform gets the value for the identifier via Symfony property accessor
because the property accessor is using getters before accessing private properties via reflection, it will return the VO
an ordinary VO cannot be used by the Symfony URL generator to create the URL
As I explained, I am using a VO for my Id as well. So I tried to figure out why it was working with the Id VO but not with the name VO.
Simple answer: the Id VO implemented the __toString method and the name VO didn't. So the solution was to let the name VO implement this method as well.
It was interesing to dig into the internal process of API Platform, but I also feel a little stupid :D

How to have a Symfony API GET call return an embedded json object instead of an IRI

I have been working on a Symfony API with Api Platform and have autogenerated all the endpoints which works fine. Except for one thing, when GETting a entity with a child entity, the child entity is not given in json but in an IRI format so this means that we get "/api/locations/1" instead of a JSON Object. I have been trying for hours but can't figure out how to change this. We are using annotations for the routes and the database relations.
You can use some nice tool like POSTMAN.
Then you can see the JSON response pretty printed.
You have to use the same, common normalization group for all embeded entities as desribed in docs.
The same is required for GraphQL when you need embeded fields other than id - asking for more than available results "Internal server error" "Cannot return null for non-nullable field XXX.YYY" - using GraphiQL helps with debugging more than POSTMAN (great tool) - when GraphQL will be working as expected, REST should be OK, too.
Unfortunatelly standard admin-on-rest doesn't like 'already fetched' values, expecting strings/IRIs only, not objects.
You can choose the response content type:

ASP.NET OData query returns properties with empty values for virtual properties in code first models

I'm currently building a ASP.NET OData service which uses code first with EF5. When I do the query of a entity, it is returned as JSON along with empty values for the related entities.
I want the related entities attributes not to be included in the returned JSON for the entity query unless 'Include' is explicitly mentioned.
Is there a way to achieve this?
You have to enable lazy loading by setting the related members as virtual

ASP.NET ScriptService prevent return of null properties in JSON

Basically I want to make my script service only serialise properties that are not null on an array of object I am returning... So this..
{"k":"9wjH38dKw823","s":10,"f":null,"l":null,"j":null,"p":null,"z":null,"i":null,"c":null,"m":0,"t":-1,"u":2}
would be
{"k":"9wjH38dKw823","s":10,"m":0,"t":-1,"u":2}
Does anyone know if this is possible?
Basically the reason for this is because null values are for unchanged properties. A local copy is kept in the javascript that is just updated to reduce traffic to the server. Change values are then merged.
You can create a custom JavaScriptConverter class for the JSON serialization process to use to handle your object, and then put the necessary logic in the Serialize method of that class to exclude the properties that are null.
This article has a clear step-by-step discussion of the process involved in creating it.
You probably would not need to actually implement the Deserialize method (can throw a NotImplementedException) if you are not passing that type of object in as an input parameter to your web services.

Resources