Hello and thanks for the support,
so I'm trying to do a custom raisefault that catches the errors from one api and reformats it. so I did this
<Payload contentType="application/json">
\{
"status": "error",
"error": \{
"code": "{response.status_code}",
"description": "{response.message}",
"subcode": "{response.subcode}"
}
}
</Payload>
everything works great but in my message its not impossible that it may contain enters and break lines that break the json format.
- is there a way to force some kind of sanitation over the variables?
- or apply transformations to the variable?
Only way I can think to do that is to run a Javascript callout first and transform the response.message variable using a regex.
Adding to Michael's response:
You'd use
var responseMessage = context.getVariable("response.message");
to access the variable in JavaScript. After transforming it, I'd recommend saving the transformed string in a different variable:
context.setVariable("response_message_str", responseMessage);
and then accessing response_message_str in your RaiseFault.
Related
I'm writing an endpoint where it logically makes sense to think of request parameters as coupled ordered pairs
(eg breed=labrador&name=fido, breed=dalmnation&name=mike etc)
Is there anything I can do to enforce this pairing from the request
(eg having a dog object such that dog1{breed=labrador&name=fido}&dog2{breed=dalmnation&name=mike} or am I to just read the parameters in order and know that given a query know that the order matters and I must trust the ordering of the parameters would follow breed,name breed,name etc?
For context my endpoint would accept [1,15] dogs in a GET request and am using Django if that makes a difference.
I'm sorry if this has been asked before or is covered elsewhere, I'm struggling to find the right words to use to find a solution on Google.
If you are using a GET request you could possibly put a json string inside one of the of the url encoded variables. Like this example with python request library:
import requests,json
dogs = [
{ "breed": "labrador", "name": "fido"},
{ "breed": "dalmnation", "name": "mike"}
]
payload = { "json": json.dumps(dogs) }
requests.get("http://endpoint", params = payload);
Then on the receiving end:
def my(request):
myDogs = json.loads(request.GET.get('json'))
I'm building a custom dynamicValue extension for paw. However i'm not able to set header in the evaluate method. See the sample code below:
evaluate(context) {
const request = context.getCurrentRequest();
request.setHeader('Content-Type', this.contentType); // <-- this gives warning
return this.createSignable(request); // This returns a base64 string.
}
I get the warning saying Javascript extension error: Cannot perform modifications and the header is not set. ( when i comment out request.setHeader call, i get no warnings)
Can anyone please help me resolve this issue?
This is correct, you cannot use setters (set any value) in a dynamic value. In fact, the way Paw evaluates dynamic values is asynchronous and as multiple evaluations can take place simultaneously it would be impossible to record the modifications. For this reason, Paw is simply denying changes and no change is persisted during evaluation.
In the documentation, it's specified that these methods (like setHeaders) is only available for importer extensions. Sorry for the inconvenience!
I think to achieve what you're trying to do, you would need two dynamic values one set in the Authorization header and one set in the Content-Type header.
Alternatively, in the future we're going to add request post-processors, so you'll be able to mutate the computed request ready to be sent to the server for additional modifications.
I know that in most MVC frameworks, for example, both query string params and form params will be made available to the processing code, and usually merged into one set of params (often with POST taking precedence). However, is it a valid thing to do according to the HTTP specification? Say you were to POST to:
http://1.2.3.4/MyApplication/Books?bookCode=1234
... and submit some update like a change to the book name whose book code is 1234, you'd be wanting the processing code to take both the bookCode query string param into account, and the POSTed form params with the updated book information. Is this valid, and is it a good idea?
Is it valid according HTTP specifications ?
Yes.
Here is the general syntax of URL as defined in those specs
http_URL = "http:" "//" host [ ":" port ] [ abs_path [ "?" query ]]
There is no additional constraints on the form of the http_URL. In particular, the http method (i.e. POST,GET,PUT,HEAD,...) used don't add any restriction on the http URL format.
When using the GET method : the server can consider that the request body is empty.
When using the POST method : the server must handle the request body.
Is it a good idea ?
It depends what you need to do. I suggest you this link explaining the ideas behind GET and POST.
I can think that in some situation it can be handy to always have some parameters like the user language in the query part of the url.
I know that in most MVC frameworks, for example, both query string params and form params will be made available to the processing code, and usually merged into one set of params (often with POST taking precedence).
Any competent framework should support this.
Is this valid
Yes. The POST method in HTTP does not impose any restrictions on the URI used.
is it a good idea?
Obviously not, if the framework you are going to use is still clue-challenged. Otherwise, it depends on what you want to accomplish. The major use case (redirection of a data subset to a new POST target) has been irretrievably broken by browser implementations (all mechanically following the broken lead of Mosaic/Netscape), so the considerations here are mostly theoretical.
I'm trying to parse the JSON response form google. This is what I currently have:
Dim x As New System.Web.Script.Serialization.JavaScriptSerializer
Dim gJson As String = ""
Dim wClient As New WebClient
wClient.Proxy = System.Net.HttpWebRequest.DefaultWebProxy
gJson = wClient.DownloadString("https://www.googleapis.com/...alt=json")
Dim results As gResponseClass = x.Deserialize(Of gResponseClass)(gJson)
gResponseClass as follows here: PasteBin
I keep getting the following exception thrown:
Invalid object passed in, member name expected. (6678): .... *the json response here* ...
Is there any blatant problems or solutions I could implement?
EDIT :
The JSON response from google: JSON Response
EDIT
Just for continuation purposes: the erros is cased indeed by the "": inside the pagemap node on facebook pages. I have resorted to calling a cleanup function as follows:
json = json.Replace(""""":", """page_id"":")
Return json
If anyone has a better way, please let me know!
Thanks again.
It looks like this is the bit of the JSON it's having trouble with:
"": [
{
"page_id": "66721388277"
}
],
I'm not a JSON expert, but I can see why it might be surprised by that. As I mentioned, it can be parsed by Json.NET (at least as a JObject) so you might want to try using that instead.
Original answer, still relevant
The DeserializeObject method specifies:
This deserialization method does not try to cast the root of the object graph to a specific type, as with the Deserialize method.
So I'd be surprised if it managed to cast to gResponseClass anyway. Have you tried using the Deserialize method instead?
(I'd have expected a compile-time error to be honest - do you have option strict and option explicit on?)
That may well not be the problem you're facing, but it's the first thing I'd look at anyway :) The JSON parses fine with JSON.NET.
I need to invoke a process which doesn't require any input from the user, just a trigger. I plan to use POST /uri without a body to trigger the process. I want to know if this is considered bad from both HTTP and REST perspectives?
I asked this question on the IETF HTTP working group a few months ago. The short answer is: NO, it's not a bad practice (but I suggest reading the thread for more details).
Using a POST instead of a GET is perfectly reasonable, since it also instructs the server (and gateways along the way) not to return a cached response.
POST is completely OK. In difference of GET with POST you are changing the state of the system (most likely your trigger is "doing" something and changing data).
I used POST already without payload and it "feels" OK. One thing you should do when using POST without payload: Pass header Content-Length: 0. I remember problems with some proxies when I api-client didn't pass it.
If you use POST /uri without a body it is something like using a function which does not take an argument .e.g int post (void); so it is reasonable to have function to your resource class which can change the state of an object without having an argument. If you consider to implement the Unix touch function for a URI, is not it be good choice?
Yes, it's OK to send a POST request without a body and instead use query string parameters. But be careful if your parameters contain characters that are not HTTP valid you will have to encode them.
For example if you need to POST 'hello world' to and end point you would have to make it look like this: http://api.com?param=hello%20world
Support for the answers that POST is OK in this case is that in Python's case, the OpenAPI framework "FastAPI" generates a Swagger GUI (see image) that doesn't contain a Body section when a method (see example below) doesn't have a parameter to accept a body.
the method "post_disable_db" just accepts a path parameter "db_name" and doesn't have a 2nd parameter which would imply a mandatory body.
#router.post('/{db_name}/disable',
status_code=HTTP_200_OK,
response_model=ResponseSuccess,
summary='',
description=''
)
async def post_disable_db(db_name: str):
try:
response: ResponseSuccess = Handlers.databases_handler.post_change_db_enabled_state(db_name, False)
except HTTPException as e:
raise (e)
except Exception as e:
logger.exception(f'Changing state of DB to enabled=False failed due to: {e.__repr__()}')
raise HTTPException(HTTP_500_INTERNAL_SERVER_ERROR, detail=e.__repr__())
return response