Guzzle - Get Raw JSON Response - json

I've been trying to get this working all day so this is my last resort.
I am trying to call an api using guzzle, and this drupal_symfony_inject module:
https://github.com/Capgemini/drupal_symfony_inject
I have the following config in hook_symfony_yaml_config_params():
// Assets client.
$assets_resources_file = $resources_folder . '/moderation.json';
$param_array['bubl_api_assets_service_client.service.description'] = $assets_resources_file;
$param_array['bubl_api_assets_client.class'] = 'BUBL\Clients\Assets\Client';
And this in my service definition:
{
"name": "BUBL moderation client",
"apiVersion": "v1",
"description": "BUBL moderation REST API client",
"operations": {
"getAllBubls": {
"httpMethod": "GET",
"uri": "/su/bubls",
"responseModel": "getJSONResponse",
"parameters": {
"before": {
"location": "uri",
"type": "integer",
"required": false
},
"after": {
"location": "uri",
"type": "integer",
"required": false
},
"max": {
"location": "uri",
"type": "integer",
"required": false
}
}
}
},
"models": {
"getJSONResponse": {
"type": "object",
"additionalProperties": {
"location": "json"
}
},
"getHTMLResponse": {
"type": "object",
"properties": {
"html": {
"location": "body",
"type": "string"
}
}
}
}
}
I have a client with the operations simply returning the response from guzzle, for example:
public function getAllBubls($before = NULL, $after = NULL) {
$response = $this->client->sendRequest('getAllBubls', ['before' => $before, 'after' => $after]);
return $response;
}
And when using it it works absolutely fine, like so:
global $_drupal_symfony_di_container;
/** #var BUBL\Clients\Moderation\Client $client */
$client = $_drupal_symfony_di_container->get('bubl_api_moderation_client');
if (is_callable(array($client, $service_name))) {
$response = $client->{$service_name}();
return $data_source = $response['bubls'];
}
Now, my problem is that the response is ran through json_decode before I get hold of it, and giving me an array, which is causing me all kinds of problems with the migrate module. I know that it is because of the
responseModel set at
"responseModel": "getJSONResponse",
However, I can't find a way to simply request a raw response. I have tried (as was alluded to in the documentation), removing the responseModal altogether and adding in:
"responseType": "primitive",
and (separately I mean)
"responseModel": "getHTMLResponse",
But unfortunately I wouldn't receive any data back with either - just an empty array. I just can't seem to find a way to ignore all of the parsing and just get the response back in JSON? Is it possible?
I've also tried to create another Model to use, but the types are either array or object, and the rest of the properties are really confusing to me in the documentation, so nothing I've tried is helping. It doesn't seem like it shouldn't go through a Model or Response Class at all, and that there is some way to bypass it perhaps ("primitive" would make sense to me, but alas not).
BTW I'm new to guzzle, and I know this seems a bit over engineered for this one call, but it is important for elsewhere, it's in place and I would like to get my head round it if it's possible to use it.
Thanks.

Ok so I found a couple of things that helped me, namely this
https://github.com/Rarst/wporg-client/blob/33fb0dcce9f170b92824d09f5717ca814d7ecd29/php/WporgService.php
Which is based on guzzle, so I took the parameters from the 'body' response response model and made this:
"getRawResponse": {
"type": "object",
"properties": {
"body": {
"location": "body",
"type": "string"
}
}
}
Which returned a Guzzle Stream. So searching for stream docs I found this
Not getting expected response from Guzzle
Which directed me to change my request to
public function getAllBubls($before = NULL, $after = NULL) {
$response = $this->client->sendRequest('getAllBubls', ['before' => $before, 'after' => $after]);
// Get the raw JSON response.
return $response['body']->getContents();
}
Which has returned to me the unparsed JSON.

Related

How to setup ResponseType (Net Core 6) based on JSON Schema

I have a large number of APIs, each without a strong class definition for output, like this
Return Ok(New With {
.ServerDecryptPass = ServerDecryptPass,
.VmConnectionAdminDecryptPass = VmConnectionAdminDecryptPass,
.DockerHubDecryptPass = DockerHubDecryptPass,
.DockerRegistryDecryptPass = DockerRegistryDecryptPass,
.VmConnectionUserDecryptPass = VmConnectionUserDecryptPass
})
Swagger, of course, doesn't see anything for response type in this case
The simplest way to formalize this JSON result is creating a JSON schema, for example in this case it looks like
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"serverDecryptPass": {
"type": "object",
"properties": {
"item1": {
"type": "array",
"items": {
"type": "number"
}
},
"item2": {
"type": "null"
}
}
},
"vmConnectionAdminDecryptPass": {
...
}
I have a hundreds of APIs and I am searching for a simple way to formalize the output of the APIs in order to generate a frontend automatically from this backend API. I searched for a simple way to setup the attribute, ProducesResponseType, based on XML schema or maybe even an example of an API result.
What is a possible solution?

Issue with JSON Schema object validation (How does it work internally)?

BACKGROUND:
I have mockedup my issue here for reference:
https://jsonschemalint.com/#/version/draft-06/markup/json?gist=4c185903d7aeb13f6977852a09cf5462
and I am using this npm package: https://www.npmjs.com/package/jsonschema
CODE
//i read in JSON specified in files (the contents of which are below) and parse them into JSON objects. This process works fine.
var jsonDef = JSON.parse(schemaFile); //i store this jsonDef in my database as an object
var jsonObj = JSON.parse(objFile);
var jsonv = new JSONValidator();
var validateResult = jsonv.validate(jsonObj, jsonDef); //jsonDef is read from my database
//validateResult.valid is true
PROBLEM:
I have a general schema + metadata definition like so ("props" contains the actual object schema I want to validate)
schemaFile:
{
"name":"schoolDemo",
"displayName":"School Demo",
"propertiesKey":"assetId",
"props":{
"assetId": {
"type": "string"
},
"grade": {
"type": "number"
}
}
}
objFile:
{
"assetId": "75255972",
"grade": "A"
}
However, when I try to validate against the following user-input object, it succeeds. Shouldn't it fail because:
(1) there is no "properties" element in the initial metadata+schema definition? This field seems to be required based on the examples shown here: https://www.npmjs.com/package/jsonschema
(2) the type for grade is not a number
What am I doing wrong?
The validation is passing because the schema is not well formed ("properties" is missing).
Try this instead and then the validation will fail:
{
"name": "schoolDemo",
"displayName": "School Demo",
"propertiesKey": "assetId",
"properties": {
"assetId": {
"type": "string"
},
"grade": {
"type": "number"
}
}
}

Stringify JSON in Logic App

We are sending messages to a service bus using a logic app. These messages will later be consumed by another service, the service expects the message content to be a string - essentially a stringified JSON object, with escape characters.
We are not able to find a method to stringify a JSON object in Logic Apps. Even if we explicitly provide a escaped string the logic app itself detects that it's stringified JSON and unescapes it and then sends it as a JSON object. We don't want that, we simply want it to send the string as it is. We have already tried changing the content type to text/plain, it does not work. The logic app always sends the unescaped string as JSON.
This post on MSDN: https://social.msdn.microsoft.com/Forums/office/en-US/e5dee958-09a7-4784-b1bf-facdd6b8a568/post-json-from-logic-app-how-to-escape-data?forum=azurelogicapps is of no help because doing this will violate the request contract of the message consuming service
Do you need the stringified message to include opening and closing double quotes?
I've tried this and it worked for me.
I have my JSON object as an output of a compose
Then, I initialised a variable with the Base64 encoded value of the escaped stringified JSON (you need to add ALL the proper escaping required,
mine was just a PoC)
Then, you send the variable already in Base64 to Service Bus. (You need to remove the encoding on that action).
"actions": {
"Compose_JSON_Object": {
"inputs": {
"message": "I want this as a string"
},
"runAfter": {},
"type": "Compose"
},
"Initialise_Variable_with_Stringified_JSON_Base64_Encoded": {
"inputs": {
"variables": [
{
"name": "jsonAsStringBase64",
"type": "String",
"value": "#base64(concat('\"', replace(string(outputs('Compose_JSON_Object')), '\"', '\\\"'), '\"'))"
}
]
},
"runAfter": {
"Compose_JSON_Object": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Send_message": {
"inputs": {
"body": {
"ContentData": "#variables('jsonAsStringBase64')",
"ContentType": "text/plain"
},
"host": {
"connection": {
"name": "#parameters('$connections')['servicebus']['connectionId']"
}
},
"method": "post",
"path": "/#{encodeURIComponent(encodeURIComponent('temp'))}/messages",
"queries": {
"systemProperties": "None"
}
},
"runAfter": {
"Initialise_Variable_with_Stringified_JSON_Base64_Encoded": [
"Succeeded"
]
},
"type": "ApiConnection"
}
},
This way, I got the message stringified.
HTH

JSON Schema Validation validate array items not working

Here is the thing I'm trying to validate:
[REMOVED AFTER EDIT - PLEASE SEE EDIT BELOW FOR UP TO DATE CODE]
This should fail because only the item that should be acceptable here is "merchants" - but the validation doesn't fail. It passes.
I've can't work this out. I've tried a few approaches and it's got me nowhere.
What is wrong here?
---------------------- EDIT ----------------------------
I've been asked to provide more code. Here is the payload I need to validate. It's in PHP.
$payload = (object) [];
$payload->query_string = (object) [];
$payload->query_string->include = (object) [
"merchant_channel",
"merchant",
];
Here is the line that will run the validator:
$this->validator->validate(
$payload,
['$ref' => 'file://Schemas/the-json-file.json']
);
And here is the file that I'm running the validator against:
{
"type": "object",
"properties": {
"query_string": {
"type": "object",
"properties": {
"include": {
"type": "object",
"properties": {
"values": {
"type": "array",
"items": {
"allOf": [
{
"type": "string",
"enum": [
"language"
]
}
]
}
}
}
}
}
}
}
}
I'm using this package:
https://github.com/justinrainbow/json-schema
This package is quite simply....
A PHP Implementation for validating JSON Structures against a given Schema.
You shouldn't have to know PHP to able to answer my original question which is specific to JSON Schema Validation!
Please don't comment/answer saying something like "You've missed a quote" or "You've missed a closing bracket". Obviously I've had to cut this code down so I can post it on Stack Overflow.
It lacks starting and ending curly braces.

Access Extended Choice Parameter Script plugin parameters in Groovy script

I used Extended Choice Parameter Script plugin and created a JSON editor with Array type as below:
disable_edit_json: true,
disable_properties: true,
disable_collapse: true,
theme: "jqueryui",
iconlib:"fontawesome4",
schema: {
"type": "object",
"title": "instances",
"properties": {
"instance": {
"type": "array",
"propertyOrder" : 1,
"format": "table",
"uniqueItems": true,
"items": {
"title": "instance",
"type": "object",
"properties": {
"url": {
"type": "string"
}
}
}
}
}
}
The parameter name is "ServerUrls". Using this I can pass one or many URLs to my Jenkins job, and I want to know the size of the array and access each of these parameter values from within a Groovy script. Conceptually something like ServerUrls.instance[0], ServerUrls.instance1 etc.
Just doing println params["ServerUrls"] throws an Exception.
Can someone please help?
It worked. The solution is as below, and it returns the value as JSON in a string format. It should be fairly easy to parse the JSON to obtain the internals of it.
def hardcoded_param = "ServerUrls"
def resolver = build.buildVariableResolver
def hardcoded_param_value = resolver.resolve(hardcoded_param)
println hardcoded_param_value