Sending a Post Request from Ballerina - http

I want to send a post request using ballerina to get a access token from the Choreo Dev Portal. I am able to do it using postman. But unable to make it work in Ballerina code level. it gives 415 - unsupported media type error. Need some Help in Ballerina
import ballerina/http;
import ballerina/io;
import ballerina/url;
public function main() returns error? {
final http:Client clientEndpoint = check new ("https://sts.choreo.dev");
http:Request request = new();
string payload = string`grant_type=urn:ietf:params:oauth:grant-type:token-exchange&
subject_token=*******&
subject_token_type=urn:ietf:params:oauth:token-type:jwt&
requested_token_type=urn:ietf:params:oauth:token-type:jwt`;
string encodedPayload = check url:encode(payload, "UTF-8");
io:print(encodedPayload);
request.setTextPayload(encodedPayload);
request.addHeader("Authorization","Basic *****");
request.addHeader("Content-Type","application/x-www-form-urlencoded");
io:print(request.getTextPayload());
json resp = check clientEndpoint->post("/oauth2/token",request);
io:println(resp.toJsonString());
}
I was expecting an access token from Choreo Devportal for the particular application.

import ballerina/http;
import ballerina/io;
import ballerina/mime;
public function main() returns error? {
// Creates a new client with the backend URL.
final http:Client clientEndpoint = check new ("https://sts.choreo.dev");
json response = check clientEndpoint->post("/oauth2/token",
{
"grant_type": "urn:ietf:params:oauth:grant-type:token-exchange",
"subject_token_type": "urn:ietf:params:oauth:token-type:jwt",
"requested_token_type":"urn:ietf:params:oauth:token-type:jwt",
"subject_token":"****"
},
{
"Authorization": "Basic ****"
},
mime:APPLICATION_FORM_URLENCODED
);
io:println(response.toString());
}
This is the recommended way to send the post request with the form URL encoded payload.

Change the Content-type header setting method from addHeader() to setHeader().
The request.setTextPayload(encodedPayload); will set the Content-type as text/plain as the default content type header.
Later request.addHeader("Content-Type","application/x-www-form-urlencoded"); is executed. The addHeader() method will append the new value to the same header in addition to the previously added text/plain. But the setHeader() will replace the previously set header which is the correct way in this scenario.
However better way is to pass the Content-type as the second param of setXXXPayload() method.
request.setTextPayload(encodedPayload, "application/x-www-form-urlencoded");

Related

FastAPI/Starlette middleware returns a StreamingResponse instead of JSONResponse

I am trying to write a FastAPI middleware to add a header to a response. The contents of the header is based on the value of the response body. This is what I have so far:
from starlette.middleware.base import BaseHTTPMiddleware
class FooMiddleware(BaseHTTPMiddleware):
async def dispatch(self, request: Request, call_next):
response = await call_next(request)
response.headers["X-Foo"] = Foo(response.content)
return response
According to the docs, FastAPI returns JSON responses as a default (https://fastapi.tiangolo.com/advanced/custom-response/?h=stream#jsonresponse), and I have done nothing to override that.
The strange thing is that the type of the response object seems to be StreamingResponse (https://fastapi.tiangolo.com/advanced/custom-response/?h=stream#streamingresponse). What is causing that?

"Handler crashed with error runtime error: invalid memory address or nil pointer dereference", but POSTMAN is ok! Why this happens?

I work with vue and go for frontend and backend respectively. I send post request to my server and get 403 error code message(notAllowed). But in postman I get the objects and is fine.
Vue and Vuex
My axios post request:
const response = await this.$axios.post(`http://localhost:8000/v1/org/${params.organization}/kkms/${params.kkm}/closeShift`,{
headers : {
'token' : this.state.token.value
}});
I know I should also use other properties like 'Content-Type' and etc in headers, but know it works well with only "token" property in the other requests. I want to know whether problem in backend or frontend?
It seems you have a mistake in the axios request.
You are receiving a 403, that means you are not authorized (or sometimes something else, check the comments in the question and down here ).
As can be found in axios docs, the post request looks like this:
axios.post(url[, data[, config]]).
It accepts the config (so the headers) as THIRD parameter, while you are setting it as second parameter. Add an empty FormData object as second param, and just shift your config to the third param.
const fakeData = new FormData();
const response = await this.$axios.post(`http://localhost:8000/v1/org/${params.organization}/kkms/${params.kkm}/closeShift`,
fakeData,
{
headers : {
'token' : this.state.token.value
}
});

Unexpected Content type in response on using Java RestAssured

I had set Content-Type in RequestSpecBuilder as "ContentType.JSON". But on making a GET request, I get Content-Type as "application/xml" in response. How do i get back a json response?
I have tried below approaches:
1. Set content type in RequestSpecBuilder object using setContentType method of RequestSpecBuilder class to "ContentType.JSON" and pass RequestSpecBuilder object in spec method of RequestSpecification --- got "application/xml" in response
Set content type in RequestSpecification object using contentType method of RequestSpecification and pass ContentType.JSON as parameter --- still got "application/xml" in response
Note: The webservice URL requires ".json" to be explicitly specified to get a json response else by default it returns a "xml" response. However, I wanted to set content type by using RequestSpecBuilder.
Eg:
for Json response: URL -- http://ergast.com/api/f1/2017/circuits.json
for Xml response: URL -- http://ergast.com/api/f1/2017/circuits
Code:
#Test
public void test_AddHeader() {
//Use of RequestSpecification
String pathUrl = "http://ergast.com/api/f1/2017/circuits";
RequestSpecBuilder requestSpecBuilder = new RequestSpecBuilder();
requestSpecBuilder = requestSpecBuilder.
setBaseUri(pathUrl).
setContentType(ContentType.JSON).
addQueryParam("limit", "10"); //added query param
RequestSpecification addRequestSpec = requestSpecBuilder.build();
RequestSpecification httpRequest = RestAssured.given().spec(addRequestSpec).contentType(ContentType.JSON);
Response httpResponse = httpRequest.get();
System.out.println(httpResponse.getContentType()); //returns application/xml
System.out.println(httpResponse.getStatusLine()); //returns HTTP/1.1 200 OK
System.out.println(httpResponse.getBody().asString());//returns XML response
}
You are expecting JSON from Response but you are passing setContentType to your RequestSpecBuilder. This will just create your POST payload in json format. It does not do anything to your response.
What you can do instead is Create a ResponseBuilder and do a setContentType to JSON there. Hope this will help you.

Arbitrary response content types in Feathers

I have a custom service that must return data in CSV format.
I can't use a standard Express route, because I need Feathers' hooks on this endpoint.
I couldn't find an example of a Feathers service returning non-HTML, non-JSON data, and have found no way to specify a response content type.
Using res.set('Content-Type', 'text/csv') before returning from the service method didn't work; the final Content-Type header was reset to application/json, even though the method's return value was a regular string.
How can I properly set arbitrary response content types in Feathers' custom service methods?
You can customize the response format like this:
const feathers = require('feathers');
const rest = require('feathers-rest');
const app = feathers();
function restFormatter(req, res) {
res.format({
'text/plain': function() {
res.end(`The Message is: "${res.data.text}"`);
}
});
}
app.configure(rest(restFormatter));
The complete documentation can be found here.
Using your own service specific middleware to send the response should also work.

Does Spring #RequestBody support the GET method?

I am trying to carry JSON data in an HTTP GET request message, but my Spring MVC server can't seem to retrieve the JSON data from the GET request body.
HTTP's GET method does not include a request body as part of the spec. Spring MVC respects the HTTP specs. Specifically, servers are allowed to discard the body. The request URI should contain everything needed to formulate the response.
If you need a request body, change the request type to POST, which does include the request body.
Based on official info
https://docs.spring.io/spring-framework/docs/4.1.0.RC2/spring-framework-reference/html/mvc.html
#RequestMapping("/something")
public ResponseEntity<String> handle(HttpEntity<byte[]> requestEntity) throws UnsupportedEncodingException {
String requestHeader = requestEntity.getHeaders().getFirst("MyRequestHeader"));
byte[] requestBody = requestEntity.getBody();
HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.set("MyResponseHeader", "MyValue");
return new ResponseEntity<String>("Hello World", responseHeaders, HttpStatus.CREATED);
}
In case anyone's here trying to get the OpenAPI generation to treat the fields of the request object as separate GET params, you'll want to use #ParameterObject (org.springdoc.api.annotations.ParameterObject) which was added here: https://github.com/springdoc/springdoc-openapi/issues/590

Resources