使用UE5的Blueprint来发送GraphQL请求

我想要在UE5中进行简单的GraphQL交互。

在市场中搜索,您可以找到处理GraphQL的内容。

然而,由于它的价格相对较高,因此我尝试写了一段能够与服务器进行简单的(无需验证等)交互的代码。

环境

ソフトウェアバージョンMacOS10.15.7UnrealEngine5.0.0Visual Studio Code1.61.2Xcode12.4.NET SDK5.0.402

基本设计

通过继承UObject,在蓝图中进行查询语句输入,并接收事件结果。项目名称将命名为GraphqlTest。

代码 (Mandarin Chinese)

在Build.cs文件的PublicDependencyModuleNames中添加Http,Json,JsonUtilities。

 PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "Http", "Json", "JsonUtilities" });
// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "Http.h" // Http関連が使用できるように追加
#include "CoreMinimal.h"
#include "UObject/NoExportTypes.h"
#include "GraphqlObject.generated.h"

/**
 * 
 */
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FBlueprintAssignableSignature);

UCLASS(Blueprintable, BlueprintType)
class GRAPHQLTEST_API UGraphqlObject : public UObject
{
    GENERATED_BODY()

public:
    UGraphqlObject();

    FHttpModule *Http;

private:

public:
    // GraphQLのサーバをBlueprintから指定できるようにプロパティを公開
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Graphql")
    FString url;

    // 受信結果をBlueprintから参照できるように読み込み専用のプロパティを追加
    UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Graphql")
    FString ContentAsString;

    // 自身のインスタンスを作成するメソッド
    UFUNCTION(BlueprintPure, Category = "Graphql", meta = (DisplayName = "Create Object", Keywords = "Create Graphql Object", ShortTooltip = "Creates an empty Graphql Object"))
    static UGraphqlObject *Create();

    // HTTP通信を行ってレスポンスが返ってきた際のイベント処理
    void OnResponseReceived(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bWasSuccessful);

    // 受診後のイベントを発行するためのメソッド
    UPROPERTY(BlueprintAssignable, Category = "Dynamic Delegate Component")
    FBlueprintAssignableSignature OnResponseReceivedDispatcherCalled;

    // クエリーを発行するためのメソッド
    UFUNCTION(BlueprintCallable, Category = "Graphql")
    void Query(FString document);
};

// Fill out your copyright notice in the Description page of Project Settings.


#include "GraphqlObject.h"

UGraphqlObject::UGraphqlObject() 
    : Super()
{
    Http = &FHttpModule::Get();
}

UGraphqlObject* UGraphqlObject::Create() {
    return NewObject<UGraphqlObject>();
}

void UGraphqlObject::OnResponseReceived(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bWasSuccessful)
{
    if (!Response.IsValid())
    {
        GEngine->AddOnScreenDebugMessage(-1, 2.0f, FColor::Green, "No Valid");
    }
    else if (EHttpResponseCodes::IsOk(Response->GetResponseCode()))
    {
        ContentAsString = Response->GetContentAsString();

        TSharedPtr<FJsonObject> JsonObject;
        TSharedRef<TJsonReader<> > Reader = TJsonReaderFactory<>::Create(ContentAsString);

        // Jsonオブジェクトをデシリアライズ
        if (FJsonSerializer::Deserialize(Reader, JsonObject))
        {
            GEngine->AddOnScreenDebugMessage(-1, 10.0f, FColor::Red, "Received JSON String");

            //ここに、JSON StringをパースしてJSON Objectとして保持する工程を追加する

            OnResponseReceivedDispatcherCalled.Broadcast();
        }
    }
}

void UGraphqlObject::Query(FString document)
{
    // Jsonデータの作成
    TSharedPtr<FJsonObject> JsonObject = MakeShareable(new FJsonObject);
    JsonObject->SetStringField("query", document);
    // JsonStringにJson書き出し
    FString JsonString;
    TSharedRef<TJsonWriter<TCHAR> > JsonWriter = TJsonWriterFactory<>::Create(&JsonString);
    FJsonSerializer::Serialize(JsonObject.ToSharedRef(), JsonWriter);

    // Httpリクエストの作成
    TSharedRef<IHttpRequest, ESPMode::ThreadSafe> Request = Http->CreateRequest();
    Request->OnProcessRequestComplete().BindUObject(this, &UGraphqlObject::OnResponseReceived);
    Request->SetURL(url);
    Request->SetVerb("POST");
    Request->SetHeader(TEXT("User-Agent"), TEXT("X-UnrealEngine-Agent"));
    Request->SetHeader(TEXT("Content-Type"), TEXT("application/json"));
    Request->SetHeader(TEXT("Accepts"), TEXT("application/json"));
    Request->SetContentAsString(JsonString);
    Request->ProcessRequest();
}

在蓝图上的装配

ノードのつなげ方.png

下部图表是执行查询的处理过程。
Query后面连接了Delay等是为了测试目的,不需要的。

インスタンス化.png

通过连接节点,可以执行查询操作,但是如果不将使用create方法创建的对象重新赋值给Blueprint变量,将无法访问对象的元素。

如果继承UActor,就不需要进行这种奇怪的连接方式,但考虑到不需要像Actor那样的功能,只继承了UObject。

补充(2021/10/29)

直接生成可能に.png

JSON不能直接导出为Blueprint。

在蓝图中似乎需要使用某种方式进行封装才能处理,但此处不涉及。

这次以文字形式输出。

我认为下面的资源会对你有所帮助。

最后

在市场上,能够处理GraphQL的实体是通过使用一种称为“潜在节点”(Latent Node)来实现,而不是通过事件处理。

这个方案在Blueprint上的操作更直观。

请提供一个具体的内容,我会根据您提供的信息进行翻译。

    • UE4でHTTP通信をしてみる – ②HTTP通信用クラスの作成 –

 

    GraphQL Serving over HTTP
广告
将在 10 秒后关闭
bannerAds