Search code examples
c++graphqlunreal-engine4

How can I send a GraphQL request from Unreal Engine C++?


I successfully made a regular HTTP request and got the response back. Now I am trying to do the same with GraphQL. The GraphQL request is returning 200 in Postman with the expected JSON body, but when I try to do the same in C++, I get a 400 Bad Request. My code is below, with access tokens removed.

AApiClient::AApiClient()
 {
     //When the object is constructed, Get the HTTP module
     Http = &FHttpModule::Get();
 }
 
 void AApiClient::BeginPlay()
 {
     Super::BeginPlay();
     MyHttpCall();
 }
 
 void AApiClient::MyHttpCall()
 {
     TSharedRef<IHttpRequest, ESPMode::ThreadSafe> Request = Http->CreateRequest();
     Request->OnProcessRequestComplete().BindUObject(this, &AApiClient::OnResponseReceived);
     
     Request->SetURL("https://{my-access-token}@{my-url}.myshopify.com/admin/api/2021-04/graphql.json");
     Request->SetVerb("POST");
     Request->SetContentAsString("{\"query\": \"{ node(id: \"gid://shopify/Product/{my-product-id}\") { id ... on Product { title } } }\"}");
     Request->SetHeader(TEXT("User-Agent"), "X-UnrealEngine-Agent");
     Request->SetHeader("Content-Type", TEXT("application/json"));
 
     Request->ProcessRequest();
     UE_LOG(LogTemp, Warning, TEXT("Request sent."));
 }
 
 void AApiClient::OnResponseReceived(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bWasSuccessful)
 {
     UE_LOG(LogTemp, Warning, TEXT("Response received"));
     UE_LOG(LogTemp, Warning, TEXT("The response code is {%i}"), Response->GetResponseCode());
     FString ResponseString = Response->GetContentAsString();
     UE_LOG(LogTemp, Warning, TEXT("The response is {%s}"), *ResponseString);
 }

One thing I should note is that it only worked in Postman after I turned on the setting labeled "Disable cookie jar". I may need to do something analogous to that in C++ but haven't discovered how that's done. Any help is appreciated.


Solution

  • I got it to work. One of the problems I was running into is explained here:

    Shopify doesn't support cookies in POST requests that use basic HTTP authentication. Any POST requests that use basic authentication and include cookies will fail with a 200 error code.

    From here: https://shopify.dev/tutorials/authenticate-a-private-app-with-shopify-admin#generate-credentials-from-the-shopify-admin

    These are the changes I made:

    1. Remove the access token from the URL.

    Request->SetURL("https://{my-shop-url}.myshopify.com/admin/api/2021-04/graphql.json");

    1. Directly set the GraphQL query as the content without removing whitespace (rather than including the query as a JSON element as in my question above).

    Request->SetContentAsString("{ node(id: \"gid://shopify/Product/{my-product-id}\") { id ... on Product { title } }}");

    1. Change the Content Type header to use GraphQL.

    Request->SetHeader("Content-Type", TEXT("application/graphql"));

    1. Add the app password as the access token header.

    Request->SetHeader("X-Shopify-Access-Token", TEXT("{my-app-password}"));

    With these changes made, I'm getting a 200 OK response with the content I'm looking for.