How to deserialize JSON-LD from ApiPlatform with PHP - symfony

I've successfully built an API for my system with ApiPlatform. Thanks to the developers it's an excellent system. I can send it requests in JSON-LD format and it returns it's responses in JSON-LD as well.
I understand the benefits of using JSON-LD, but I feel like I am missing a big piece of the puzzle. How to deserialize to PHP objects, using the embedded JSON-LD context, in my Symfony based PHP client that is to consume the API.
Say I have the following response from my API
{
"#context": "/contexts/CallbackRequest",
"#id": "/callback-requests/72",
"#type": "CallbackRequest",
"id": 72,
"created": "2017-09-22T08:07:25+02:00",
"customer": {
"#id": "/customers/13",
"#type": "Customer",
"id": 13,
"firstName": "Joe",
"lastName": "Bloggs",
"email": "joe#bloggs.com",
"mobilePhone": "123456789"
}
}
Now there is enough information available in here to deserialize to the 2 PHP objects CallbackRequest with nested object Customer thanks to the JSON-LD #context and #type data.
I have written my own denormalizer, but I have to tell the serializer what kind of object I want to deserialize to first, but I can't extract this from the JSON-LD without normalizing it first.
I have searched around a lot looking for anyone who has made a JSON-LD normalizer/denormalizer for the Symfony serializer but have found nothing (with the exception of this functionality inside the API Platform package itself).
Can anybody provide me any pointers, either to a JSON-LD denormalizer package that I can implement, or any suggestions on how to implement the Symfony serializer to denormalize JSON-LD without knowing the what object it is supposed to contain in advance.
Thank you

Related

Alexa Skill Developers Reference-Based Catalog Management API

This doc says "With the Reference-Based Catalog Management API, you can create a custom slot type that references an external data source to get the slot type values. This API allows you to create and maintain a catalog of slot type values independent of your Alexa skill."
However as you dig into it, it doesn't provide some needed details on how to actually setup the catalog on an endpoint like s3.
While this resource was provided as an answer in this similar question, it actually refers to content catalogs (like music playlists), not the Reference-Based Catalog Management API, so I assume that was in error and it is not applicable.
So, for the Reference-Based Catalog Management API: The docs say it needs to be in JSON format, and offers ingredients.json as an example. However I used this directly, and it fails (see below). Also, it does not describe what the format should be to include synonyms. Please describe this.
I can successfully create the catalog with '/v1/skills/api/custom/interactionModel/catalogs/' and get a catalogId in return. However, creating the catalog version via '/skills/api/custom/interactionModel/catalogs/{catalogId}/versions' fails. I get "Website Temporarily Unavailable" when I issue the POST.
Here's the request body structure that I'm including with that post:
data: {
"source": {
"type": "URL",
"url": "https://s3.amazonaws.com/..../ingredients.json"
},
"description": "test S3 bucket"
}
Also, does the S3 endpoint have to be made public? I tried it both ways, didn't seem to matter. If it does have to be public though, how did you handle security?
Thanks for the help.
While the API call fails, I did get this to work using the CLI approach.
ask api create-model-catalog-version -c {catalogID} -f {filename}
The file should be JSON with the following structure:
{
"type": "URL",
"url": "[your catalog url]"
}
It remains an open question how to get the API approach to work, so any answers appreciated. Maybe it is a bug, because I specify the exact same 'source' definition in the data structure of the API call as I do in the JSON file used by the CLI command.
Here's what I learned as I got it to work with the CLI:
Yes, the S3 endpoint must be made public in order for the create-model-catalog-version job to succeed. This strikes me as a problem, would like to see the ability to wrap some security around these endpoints.
Here is the format of the JSON that you will want to use, including the use of synonyms which is not described in the official Amazon example. Note that you don't have to include an ID as shown in that example.
{
"values": [
{
"name": {
"value": "hair salon",
"synonyms": [
"hairdresser",
"beauty parlor"
]
}
},
{
"name": {
"value": "hospital",
"synonyms": [
"emergency room",
"clinic"
]
}
},
]
}

ApplicationError: LinkId(s) specified in request are not available

I'm using the HERE Route Match Extension API for matching GPX Data to a route. Afterwards, I am using the road links from the matched route for querying the Routing API. This worked perfectly some weeks ago; strangely I am now getting this error for some of the road links from the Route Match Extension API (response from the Routing API):
"_type": "ns2:RoutingServiceErrorType",
"type": "ApplicationError",
"subtype": "LinkIdNotFound",
"details": "LinkId(s) specified in request are not available",
"additionalData": [
{
"key": "LinkId[0]",
"value": "-1224766809"
}
]
In the response from the Route Match Extension API, the road link definitely exists:
{"confidenceValue":0.6,"elevation":188.39999999999998,"headingDegreeNorthClockwise":10000.0,"headingMatched":118.0,"lat":49.67599245719612,"latMatched":49.67605,"linkIdMatched":-1224766809,"lon":10.035531716421247,"lonMatched":10.03558,"matchDistance":8.36,"matchOffsetOnLink":0.6588415883643146,"minError":1000000.0,"routeLinkSeqNrMatched":178,"speedMps":0.0,"timestamp":1532677148000}
Here is an example query link for the above error: https://route.api.here.com/routing/7.2/calculateroute.json?waypoint0=geo!49.77763,9.95697&waypoint1=link!-1224766809&mode=fastest%3Bcar%3Btraffic%3Aenabled&app_id=devportal-demo-20180625&app_code=9v2BkviRwi9Ot26kp2IysQ&representation=linkPaging&language=de-de&returnElevation=true&maneuverAttributes=position%2Clength%2CtravelTime%2CstartAngle&instructionFormat=text&routeAttributes=waypoints%2Csummary
What's going on here? Is this just a temporary issue, since it used to work some weeks ago?
Underlying map release for RME and routing api could be different which leads to link id in both not matching. It is recommended to use lat, long for the routing api.
Routing api and extensions api map release cycles are different and you wont be able to change them. It is better to use the lat, lon rather than relying on link id for your usecase. Using the lat, long from your rme response I get a different link id in routing api. https://route.cit.api.here.com/routing/7.2/calculateroute.json?waypoint0=geo!49.77763,9.95697&waypoint1=geo!49.67599245719612,10.035531716421247&mode=fastest%3Bcar%3Btraffic%3Aenabled&app_id=<>&app_code=<>&representation=linkPaging&language=de-de&returnElevation=true&maneuverAttributes=position%2Clength%2CtravelTime%2CstartAngle&instructionFormat=text&routeAttributes=waypoints%2Csummary

How to use api edit phabricator repository URI

I want to add repository URI and set it to observe mode, so I tried to change default URI I/O mode from Read/Write to No IO. I tried diffusion.uri.edit, in repository key description, it said:
This transaction type must be present when creating a new URI and must
not be present when editing an existing URI.
I tested it with web conduit/method/diffusion.uri.edit. In transactions, I use
[
{"type": "uri","value": "ssh://git#05.mm.net/diffusion/TESTPROCESS/test-process.git"},
{"type": "io","value": "none"}
]
It report Validation errors:
When creating a repository URI, you must specify which repository the
URI will belong to.
I also tried add repository key such as
[
{"type": "uri","value": "ssh://git#git.missfresh.cn:test/test-process.git"},
{"type": "io","value": "none"},
{"type": "repository","value": "PHID-REPO-c7jajliasqtxoclryfim"}
]
It will create a new URI. What's the correct value for diffusion.uri.edit?
I found the answer. The transactions parameters are correct, but objectIdentifier is needed also, its value is the URI ID.

sending dictionary parameter with jmeter to rest service

First of all i am a newbie at jmeter. I searched a lot of documents but unfortunately i did not find to answer for my problem. I have a web api rest service with following sign. I can't send dictionary format parameter.
[HttpPost,ActionName("DummyService")]
public Dictionary<string,string> DummyService([FromBody] Dictionary<string,string> parameters)
I used Parameters section and BodyData section but parameters are always null.
How can i achieve that?
Thanx in advance.
I believe you need to pass some form of a JSON Array to your web service, in order to do it:
Switch to Body Data tab
Put your JSON payload there like:
{
"Parameters": [
{
"Key": "Key1",
"Value": "Value1"
},
{
"Key": "Key2",
"Value": "value2"
}
]
}
Most likely you will need to add a HTTP Header Manager to your test plan and configure it to send Content-Type header with the value of application/json
(optional) Consider upgrading to JMeter 3.0, looking into screenshot it seems you're sitting on an older version
See Testing SOAP/REST Web Services Using JMeter guide for more information on setting up JMeter for API testing

Where does the default JSON errors response in spring-boot-starter-web comes from and how to adjust it?

I am very happy with the spring-boot project so far, but I'd like to develop a deeper understanding, of how everything is glued together. Using spring-boot-starter-web, spring-boot-starter-data-jpa and hateoas I was able to assemble a nice working REST backend. But I am wondering, how it is done, that e.g. a DataIntegrityViolation is converted nicely into a JSON output like this. I actually like the info being provided, but I wonder, how I could reuse the DataObject being converted to JSON. I just do not understand, where it comes from and where it is configure. Hope you folks can help me out or point me to the relevant parts of documentation or even source code.
{
"readyState": 4,
"responseText": "{\"timestamp\":1423155860435,\"status\":500,\"error\":\"Internal Server Error\",\"exception\":\"org.springframework.dao.InvalidDataAccessResourceUsageException\",\"message\":\"could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet\",\"path\":\"/api/catalog/colorfamilies\"}",
"responseJSON": {
"timestamp": 1423155860435,
"status": 500,
"error": "Internal Server Error",
"exception": "org.springframework.dao.InvalidDataAccessResourceUsageException",
"message": "could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet",
"path": "/api/catalog/colorfamilies"
},
"status": 500,
"statusText": "Internal Server Error"
}
Thx for your help,
Marius
The output is created by Spring Boot's BasicErrorController. It's used as a fallback when your application hasn't handled an exception using Spring MVC (with an ExceptionHandler or ControllerAdvice, for example) or a container error page.
The JSON is created by an implementation of ErrorAttributes. By default, Spring Boot will use DefaultErrorAttributes. You can customise this by creating your own #Bean that implements ErrorAttributes.
See the error handling section of the Spring Boot documentation for more information.

Resources