Cannot create a new entity (created with ECK) through API using REST module - drupal

Here is my situation: I am using the ECK module with Drupal 8 to create entities and bundles, and the new REST core module to create API features.
I have installed the REST_UI module, and I enabled the route for the entity I am interested in.
Here's my issue: I created an entity type and a bundle with ECK, and I can then create a new entity when I am calling the /entity/entity_type_name endpoint with a POST request, giving the following parameter as json:
{
"type":[{"target_id":"bundle_name"}],
"field_test_text":[{"value":"test"}]
}
However, this is only working when I have only one entity type in my list of entities; Let's say for example I decide to create a new entity type, then run the same request, I got the following error message:
Drupal\Core\Entity\Exception\AmbiguousEntityClassException: Multiple entity types found for Drupal\eck\Entity\EckEntity
I understand that apparently, now that I have multiple entity types, the Entity API is not able to understand what should be the type of the entity it has to create (which I find pretty weird, considering that I am providing it in the URL under this form /entity/entity_type_name and that there are different routes available for the different types of entities that I have).
I guess I need to pass an extra parameter in my json for Drupal to understand what kind of entity it should create, but what would be this parameter ? I've been trying to look online and in the documentation, but I cannot figure out how to do this.

I had the same problem, and here is how I resolved it:
Enable the HAL module.
Enable hal_json under Accepted request formats in /admin/config/services/rest for
that particular resource.
Then, in your POST request, use headers:
Content-Type: application/hal+json
X-CSRF-Token: [AUTH SESSION TOKEN]
And the body of the request being:
{
"_links": {
"type": {
"href": "http://localhost:8080/rest/type/[ENTITY_TYPE]/[ENTITY_BUNDLE]"
}
},
"title":[
{"value": "This is a new entity title"}
],
"field_example":[
{"value": "This is an example of a custom text field value."}
]
}
Drupal is reading the entity type and bundle from the _links.type.href string.
For example, if your entity type was automobile and your bundle was car, your URL would be "http://localhost:8080/rest/type/automobile/car"

Related

How do I create JSON type in entity in Symfony

I am actually looking for a way to validate elements in json. I thought there is a way to list them out to strictly avoid accepting wrong elements. For instance instead of "gender": "male" as illustrated below, someone could send "sex": "male" and I am trying to avoid it.
I have a data field (column) called Profile
profile = {'name': 'Payne', 'gender': 'male', 'favourites': [{'drinks': 'soda'}, {'colour': 'blue'}, {'game': 'scrabble'}], 'dob': '1962'}
I am using a third party API to populate the database using HttpClient.
My response is returning JSON and I want to make some decisions with it and store it in the database but I need to validate it in conformity with what is expected strictly.
About validation:
If you know how to do it with arrays, you can still decode it and validate it as an array, then encode it again. Symfony has a validator service but I do not know exactly how to correctly use it in all cases.
The official Symfony documentation for the Validator Service and how to use it can be found in this link and it's anchor:
https://symfony.com/doc/current/validation.html
https://symfony.com/doc/current/validation.html#using-the-validator-service
Some info about JSON in PHP:
The most typical use for json, even for updating and downloading content to and from a DataBase, is the use of json_encode() and json_decode(), which will basically help you make your arrays more "portable" in different use cases.
For example, in MySQL, which accepts the JSON type, you can insert arrays into a column by encoding them with JSON.
If you want to declare a JSON type variable in Symfony, you can do it as in this example:
/**
* #ORM\Column(type="json", ...)
*/
private $yourColumn;
Both json_encode() and json_decode() are available since PHP v5.2.0
As an example of a DB, the JSON type was added to MySQL in version 5.7.8 (https://dev.mysql.com/doc/refman/5.7/en/json.html)
You should take a look at these links:
https://www.php.net/manual/es/function.json-encode.php
https://www.php.net/manual/es/function.json-decode.php
https://www.w3schools.com/js/js_json_php.asp
https://dev.mysql.com/doc/refman/8.0/en/

How to make dynamic input parameters based on another query response in an Integromat app?

I am implementing an API that has an endpoint which returns a list of custom fields for objects such as company, lead, etc.
When creating a lead, the user should be able to enter custom fields alongside the hardcoded ones.
How can this be done dynamically in the Mappable parameters of a module?
You can create an RPC (procedure for getting of dynamic input fields via API) and combine it with static parameters like in the example below:
Mappable parameters:
[
{
"name": "id",
"type": "uinteger",
"label": "Static parameter"
},
"rpc://getDynamicFields"
]
Ref: https://docs.integromat.com/apps/structure-blocks/expect#rpc
How to create RPC you can find here: https://docs.integromat.com/apps/app-structure/rpcs#fields-rpc

Should JSON API entities include a relationship for its parent?

I haven't been able to find a clear answer, hoping someone can help.
If we have, say, a blog with posts, and each post can have comments, and each comment a related user. Is it against convention, if I request the comment, to include both the user and the post in the relationships?
data: {
type: 'comments',
id: '1',
relationships: {
post: {...}, //should this be here?
user: {...},
}
attributes: {...},
},
included: {...}
As paulsm4 correctly stated: "it is up to you".
But I can give you some advice about that.
In such situations, you can give the caller of the API the choice of having such links or not via a querystring flag, like
?relationships=post,user
In this case, if you do not specify the relationship flag, you'll get the simple comment data or you can decide to give them all; in the second case, you can use relationships as a sort of filter.
In some APIs, I've seen also a more invasive approach: embed the related object directly in the returned JSON.
With the same technique as before:
?embed=post,user
This should produce an embedded JSON object in the current JSON reply including the original objects just as you were asking something like "GET /post/123" or "GET /user/456" separately. This can be handy in some situations.
Often this flag is named "expand" denoting same or similar behaviour.
For an example open this API documentation from Atlassian and search for "expand".
It does exist an old "standard" for your problem called HAL that speaks about linking and embedding in REST APIs.
Even the Wordpress API offers such features, give it a look in the official documentation.
An alternative to this is to rewrite the entire API in GraphQL leveraging the REST approach.
Q: Should JSON API entities include a relationship for its parent?
A: I assume that's entirely up to you!
If your JSON is defined by some third party, then you have to live with what they gave you. Please post details on how the JSON is specified.
Otherwise, if you're "inventing" the format yourself:
One possibility is to have a relationships: field with a link to the "parent".
Perhaps a better solution might to invent a "container" (perhaps a simple array!) to hold your "records".
If this were a database, I'd have a "posts" table, and a "comments" table. The "comments" table would have a "Post ID" column as a foreign key into the "posts" table.
'Hope that helps ... at least a bit...
JSON API specification does not make any requirements on the attributes and relationships being included in a resource object. The specification is just saying how they must be formatted if they are included. If I did not missed anything, specification does not even require that all resource objects of the same type must have same attributes and relationships.
But I would argue that there isn't any value in not including the relationships. JSON API specification does not require a relationship object to include resource linkage data. On the contrary it's only talking about resource linkage data in context of a compound document, in which it's used "to link together all of the included resource objects without having to GET any URLs via links."
It's totally valid and could be considered best practice to only provide related resource link if the related resources are not included in the payload. Constructing such a link would not put any workload on your server since it does not require to query the database. It also does not make any relevant difference in payload size.
An example of a payload using both techniques would look like this. It assumes that the request explicitly asked to include related user using include query param.
// GET https://examples.com/api/v1/comments/1?include=user
{
data: {
type: 'comments',
id: '1',
relationships: {
post: {
links: {
related: 'https://examples.com/api/v1/comments/1/post'
}
},
user: {
data: {
type: 'users',
id: '2'
},
links: {
related: 'https://examples.com/api/v1/comments/1/user'
}
},
}
},
included: [
{
type: 'users',
id: '2',
attributes: {
name: 'John Doe'
}
}
]
}
You may also want to include a relationship link, which "allows the client to directly manipulate the relationship." Update relationships chapter of spec gives a deep dive into what you could accomplish using relationship links.

How to send Json to Azure Appinsights with c# library

I'm implementing the Azure's Application Insights and the API I found is I can only send there Dictionary of type string and string. Also if I use TraceTelemetry it has properties on it which again is dictionary of string and string.
However when I add one field to the custom properties (cars in my case) which has value of serialized json it will result in such a payload being sent to the Application Insights.
"baseData": {
"ver": 2,
"message": "Test Message",
"properties": {
"cars": "[{\"Id\":0,\"Price\":{\"Value\":12.32,\"Currency\":.....
}
}
notice the backslash making it one json value.
But the appinsight portal will understand it - and parse it.
So I can use Microsoft provided C# API but it just looks ugly and seems like the API is JSON anyway, so why is API limited to Dictionary<string, string> ?
It is because of filtering in Azure Portal. The main purpose of Properties (Dictionary<string, string>) is provide the ability to find specified requests, exceptions etc. You are also limited by count of properties (it was about 200). The typical properties are: "username", "isAuthenticated", "role", "score", "isAnonymous", "portalName", "group", "product" atc. Typically global properties.
If you want to send whole object / json, you can use TrackTrace(). You can find all the traces regarding to concrete request in portal.

Reading data from CMF/PHPCR

I'm trying to use CMF for backoffice content edition. For the purposes of local content edition, CMF works fine. But then, I want to send this data to another server using a custom data structure, one that is completely different from what PHPCR uses.
Does CMF provide any kind of API or service to query its repository? For instance, my entities are Pages which contain Sections which contain Articles that finally contain the properties "title" and "body". I want to send this structure as a JSON to another server without all the overhead present in PHPCR.
{
pageTitle: "Home",
sections: [
{
sectionTitle: "firstSection",
articles: [
{
title: "Hello",
body: "Welcome to this page"
}
]
}
]
}
The CMF provides quite a few components, so I am not sure exactly which you want to use and which you want to skip.
For example for the inline editing, you could point things to a different JSON-LD capable backend.
If you want to use Sonata for administration, then it gets a bit more complicated. In theory you can create a new Jackalope transport layer that simply talks to some REST service which will enable CMF to read/write from it just like with the other Jackalope transports. In fact I have done a proof of concept once to use the Prismic.io service in exactly this way, though I only implemented the read part.
Maybe the best way to answer your question is if you could state which parts of the CMF you do want to use, rather than just say you do not want to use any of the existing PHPCR implementations.

Resources