IN THIS ARTICLE
Generated Game Client Code Example
Generated Game Client Code Example
The following client code was generated by the swagger.json
file for the Message of the Day Gem that is included with Lumberyard. The swagger file for the gem defines many operations. For brevity, the example shows client code for only the following GET
and PUT
operations:
GET /admin/messages?index={index}&count={count}&filter={filter}
PUT /admin/messages/{msg_id}
For comments, see the Examining the Generated Game Client Code section that follows the example.
// Example Generated Game Client
#pragma once
#include <AzCore/Component/Component.h>
#include <AzCore/Component/Entity.h>
#include <AzCore/Component/ComponentBus.h>
#include <AzCore/EBus/EBus.h>
#include <AzCore/Memory/SystemAllocator.h>
#include <AzCore/Rtti/BehaviorContext.h>
#include <AzCore/Serialization/EditContext.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/std/smart_ptr/scoped_ptr.h>
#include <AzCore/std/string/conversions.h>
#if defined (PLATFORM_SUPPORTS_AWS_NATIVE_SDK)
#include <aws/core/http/HttpRequest.h>
#include <aws/core/http/HttpResponse.h>
#endif // (PLATFORM_SUPPORTS_AWS_NATIVE_SDK)
#include <LmbrAWS/ILmbrAWS.h>
#include <CloudGemFramework/ServiceRequestJob.h>
#include "StdAfx.h"
namespace CloudGemMessageOfTheDay {
namespace ServiceAPI {
const char* LmbrAWS_CodeGen_PutAdminMessagesReturnType_UUID= "{ec889bb0-c329-11e6-b753-80a589a02a3d}";
const char* LmbrAWS_CodeGen_Component_UUID= "{ec8874a1-c329-11e6-accd-80a589a02a3d}";
const char* LmbrAWS_CodeGen_ResponseHandler_UUID= "{ec8874a4-c329-11e6-a067-80a589a02a3d}";
const char* LmbrAWS_CodeGen_NotificationBus1_UUID= "{ec8874a2-c329-11e6-a661-80a589a02a3d}";
const char* LmbrAWS_CodeGen_RequestBus1_UUID= "{ec8874a3-c329-11e6-a1e9-80a589a02a3d}";
const char* LmbrAWS_CodeGen_DeleteAdminMessagesReturnType_UUID= "{ec889bb1-c329-11e6-aa94-80a589a02a3d}";
const char* LmbrAWS_CodeGen_DetailedMessageList_UUID= "{ec889bb4-c329-11e6-8650-80a589a02a3d}";
const char* LmbrAWS_CodeGen_ServiceStatus_UUID= "{45baaccf-c88b-11e6-b813-80a589a02a3d}";
const char* LmbrAWS_CodeGen_DetailedMessageData_UUID= "{ec889bb3-c329-11e6-bf48-80a589a02a3d}";
// redefs
bool WriteJson(CloudGemFramework::JsonWriter& writer, const int& item)
{
return writer.Int(item);
}
bool WriteJson(CloudGemFramework::JsonWriter& writer, const AZStd::string& item)
{
return writer.String(item);
}
bool WriteJson(CloudGemFramework::JsonWriter& writer, const float& item)
{
return writer.Double(static_cast<double>(item));
}
struct PutAdminMessagesReturnType
{
AZ_TYPE_INFO(PutAdminMessagesReturnType, LmbrAWS_CodeGen_PutAdminMessagesReturnType_UUID)
AZ_CLASS_ALLOCATOR(PutAdminMessagesReturnType, AZ::SystemAllocator, 0)
bool OnJsonKey(const char* key, CloudGemFramework::JsonReader& reader);
static void Reflect(AZ::ReflectContext* reflection);
};
bool WriteJson(CloudGemFramework::JsonWriter& writer, const PutAdminMessagesReturnType& item)
{
bool ok = true;
ok = ok && writer.StartObject();
ok = ok && writer.EndObject();
return ok;
}
struct DetailedMessageData
{
AZ_TYPE_INFO(DetailedMessageData, LmbrAWS_CodeGen_DetailedMessageData_UUID)
AZ_CLASS_ALLOCATOR(DetailedMessageData, AZ::SystemAllocator, 0)
int priority;
AZStd::string message;
AZStd::string endTime;
AZStd::string UniqueMsgID;
AZStd::string startTime;
bool OnJsonKey(const char* key, CloudGemFramework::JsonReader& reader);
static void Reflect(AZ::ReflectContext* reflection);
};
bool WriteJson(CloudGemFramework::JsonWriter& writer, const DetailedMessageData& item)
{
bool ok = true;
ok = ok && writer.StartObject();
ok = ok && writer.Key("priority");
ok = ok && WriteJson(writer, item.priority);
ok = ok && writer.Key("message");
ok = ok && WriteJson(writer, item.message);
ok = ok && writer.Key("endTime");
ok = ok && WriteJson(writer, item.endTime);
ok = ok && writer.Key("UniqueMsgID");
ok = ok && WriteJson(writer, item.UniqueMsgID);
ok = ok && writer.Key("startTime");
ok = ok && WriteJson(writer, item.startTime);
ok = ok && writer.EndObject();
return ok;
}
using DetailedMessageListPropertyList = AZStd::vector<DetailedMessageData>;
bool WriteJson(CloudGemFramework::JsonWriter& writer, const DetailedMessageListPropertyList& list)
{
bool ok = true;
ok = ok && writer.StartArray();
for (auto item : list)
{
ok = ok && WriteJson(writer, item);
}
ok = ok && writer.EndArray();
return ok;
}
struct DetailedMessageList
{
AZ_TYPE_INFO(DetailedMessageList, LmbrAWS_CodeGen_DetailedMessageList_UUID)
AZ_CLASS_ALLOCATOR(DetailedMessageList, AZ::SystemAllocator, 0)
DetailedMessageListPropertyList list;
bool OnJsonKey(const char* key, CloudGemFramework::JsonReader& reader);
static void Reflect(AZ::ReflectContext* reflection);
};
bool WriteJson(CloudGemFramework::JsonWriter& writer, const DetailedMessageList& item)
{
bool ok = true;
ok = ok && writer.StartObject();
ok = ok && writer.Key("list");
ok = ok && WriteJson(writer, item.list);
ok = ok && writer.EndObject();
return ok;
}
// Service RequestJobs
CLOUD_GEM_SERVICE(CloudGemMessageOfTheDay);
void Configure()
{
// Insert any necessary CloudGemFramework configuration here
}
class PutAdminMessagesRequest
: public CloudGemFramework::ServiceRequest
{
public:
SERVICE_REQUEST(CloudGemMessageOfTheDay, HttpMethod::HTTP_PUT, "/admin/messages/{msg_id}");
struct Parameters
{
AZStd::string msg_id;
MessageData msg;
bool BuildRequest(CloudGemFramework::RequestBuilder& request)
{
bool ok = true;
ok = ok && request.SetPathParameter("{""msg_id""}", msg_id);
ok = ok && request.WriteJsonBodyParameter(*this);
return ok;
}
bool WriteJson(CloudGemFramework::JsonWriter& writer) const
{
bool ok = true;
ok = ok && CloudGemMessageOfTheDay::ServiceAPI::WriteJson(writer, msg);
return ok;
}
};
PutAdminMessagesReturnType result;
Parameters parameters;
};
using PutAdminMessagesRequestJob = CloudGemFramework::ServiceRequestJob<PutAdminMessagesRequest>;
class GetAdminMessagesRequest
: public CloudGemFramework::ServiceRequest
{
public:
SERVICE_REQUEST(CloudGemMessageOfTheDay, HttpMethod::HTTP_GET, "/admin/messages");
struct Parameters
{
int index;
int count;
AZStd::string filter;
bool BuildRequest(CloudGemFramework::RequestBuilder& request)
{
bool ok = true;
ok = ok && request.AddQueryParameter("index", index);
ok = ok && request.AddQueryParameter("count", count);
ok = ok && request.AddQueryParameter("filter", filter);
ok = ok && request.WriteJsonBodyParameter(*this);
return ok;
}
bool WriteJson(CloudGemFramework::JsonWriter& writer) const
{
bool ok = true;
return ok;
}
};
DetailedMessageList result;
Parameters parameters;
};
using GetAdminMessagesRequestJob = CloudGemFramework::ServiceRequestJob<GetAdminMessagesRequest>;
// Notification bus for this component
class CloudGemMessageOfTheDayNotifications
: public AZ::ComponentBus
{
public:
/**
* Sent when the request is a success
*
* Params:
* jsonOutput: The output receieved from the Lambda call
* request: The AWS Lambda request object
*/
virtual void OnPutAdminMessagesRequestSuccess(const PutAdminMessagesReturnType response) { }
/**
* Sent when the request fails
*
* Params:
* error: The output receieved from the Lambda call;
* could be function error or an issue with the request
* request: The AWS Lambda request object
*/
virtual void OnPutAdminMessagesRequestError(const CloudGemFramework::Error error) { }
/**
* Sent when the request is a success
*
* Params:
* jsonOutput: The output receieved from the Lambda call
* request: The AWS Lambda request object
*/
virtual void OnGetAdminMessagesRequestSuccess(const DetailedMessageList response) { }
/**
* Sent when the request fails
*
* Params:
* error: The output receieved from the Lambda call;
* could be function error or an issue with the request
* request: The AWS Lambda request object
*/
virtual void OnGetAdminMessagesRequestError(const CloudGemFramework::Error error) { }
};
using CloudGemMessageOfTheDayNotificationBus = AZ::EBus<CloudGemMessageOfTheDayNotifications>;
class BehaviorCloudGemMessageOfTheDayNotificationBusHandler
: public CloudGemMessageOfTheDayNotificationBus::Handler, public AZ::BehaviorEBusHandler
{
public:
AZ_EBUS_BEHAVIOR_BINDER(BehaviorCloudGemMessageOfTheDayNotificationBusHandler, LmbrAWS_CodeGen_NotificationBus1_UUID, AZ::SystemAllocator
, OnPutAdminMessagesRequestSuccess
, OnPutAdminMessagesRequestError
, OnGetAdminMessagesRequestSuccess
, OnGetAdminMessagesRequestError
);
void OnPutAdminMessagesRequestSuccess(const PutAdminMessagesReturnType response) override
{
Call(FN_OnPutAdminMessagesRequestSuccess, response);
}
void OnPutAdminMessagesRequestError(const CloudGemFramework::Error error) override
{
Call(FN_OnPutAdminMessagesRequestError, error);
}
void OnPostAdminMessagesRequestSuccess(const DetailedMessageData response) override
{
Call(FN_OnPostAdminMessagesRequestSuccess, response);
}
void OnPostAdminMessagesRequestError(const CloudGemFramework::Error error) override
{
Call(FN_OnPostAdminMessagesRequestError, error);
}
};
class CloudGemMessageOfTheDayResponseHandler;
// Request bus for this component
class CloudGemMessageOfTheDayRequests
: public AZ::ComponentBus
{
public:
virtual ~CloudGemMessageOfTheDayRequests() {}
virtual void PutAdminMessages(const AZStd::string& msg_id, const MessageData& msg, CloudGemMessageOfTheDayResponseHandler* responseHandler) { }
virtual void GetAdminMessages(const int& index, const int& count, const AZStd::string& filter, CloudGemMessageOfTheDayResponseHandler* responseHandler) { }
};
using CloudGemMessageOfTheDayRequestBus = AZ::EBus<CloudGemMessageOfTheDayRequests>;
// This class is used as a parameter for all requests and throws the response on the CloudGemMessageOfTheDayNotificationBus
// Inherit from this to define custom behavior.
class CloudGemMessageOfTheDayResponseHandler
{
public:
AZ_TYPE_INFO(CloudGemMessageOfTheDayResponseHandler, LmbrAWS_CodeGen_ResponseHandler_UUID)
AZ_CLASS_ALLOCATOR(CloudGemMessageOfTheDayResponseHandler, AZ::SystemAllocator, 0)
virtual ~CloudGemMessageOfTheDayResponseHandler() {}
virtual void HandlePutAdminMessagesSuccess(PutAdminMessagesRequestJob* job, AZ::Entity* entity)
{
EBUS_EVENT_ID(entity->GetId(), CloudGemMessageOfTheDayNotificationBus, OnPutAdminMessagesRequestSuccess, job->result);
}
virtual void HandlePutAdminMessagesError(PutAdminMessagesRequestJob* job, AZ::Entity* entity)
{
EBUS_EVENT_ID(entity->GetId(), CloudGemMessageOfTheDayNotificationBus, OnPutAdminMessagesRequestError, job->error);
}
virtual void HandleGetAdminMessagesSuccess(GetAdminMessagesRequestJob* job, AZ::Entity* entity)
{
EBUS_EVENT_ID(entity->GetId(), CloudGemMessageOfTheDayNotificationBus, OnGetAdminMessagesRequestSuccess, job->result);
}
virtual void HandleGetAdminMessagesError(GetAdminMessagesRequestJob* job, AZ::Entity* entity)
{
EBUS_EVENT_ID(entity->GetId(), CloudGemMessageOfTheDayNotificationBus, OnGetAdminMessagesRequestError, job->error);
}
};
class CloudGemMessageOfTheDayClientComponent
: public AZ::Component
, public CloudGemMessageOfTheDayRequestBus::Handler
{
public:
AZ_COMPONENT(CloudGemMessageOfTheDayClientComponent, LmbrAWS_CodeGen_Component_UUID);
virtual ~CloudGemMessageOfTheDayClientComponent() = default;
AZStd::scoped_ptr<CloudGemMessageOfTheDayResponseHandler> m_defaultResponseHandler;
void Init() override
{
m_defaultResponseHandler.reset(new CloudGemMessageOfTheDayResponseHandler());
CloudGemMessageOfTheDay::ServiceAPI::Configure();
}
void Activate() override
{
CloudGemMessageOfTheDayRequestBus::Handler::BusConnect(m_entity->GetId());
}
void Deactivate() override
{
CloudGemMessageOfTheDayRequestBus::Handler::BusDisconnect();
}
static void Reflect(AZ::ReflectContext* reflection)
{
MessageData::Reflect(reflection);
PutAdminMessagesReturnType::Reflect(reflection);
DetailedMessageData::Reflect(reflection);
DetailedMessageList::Reflect(reflection);
MessageList::Reflect(reflection);
AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(reflection);
if (serializeContext)
{
// we must include any fields we want to expose to the editor or lua in the serialize context
serializeContext->Class<CloudGemMessageOfTheDayClientComponent>()
->Version(1);
AZ::EditContext* editContext = serializeContext->GetEditContext();
if (editContext)
{
editContext->Class<CloudGemMessageOfTheDayClientComponent>("CloudGemMessageOfTheDayClientComponent", "CloudGemMessageOfTheDay Component")
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
->Attribute(AZ::Edit::Attributes::Category, "Cloud Canvas Gems")
->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("Game"));
}
}
AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(reflection);
if (behaviorContext)
{
behaviorContext->EBus<CloudGemMessageOfTheDayRequestBus>("CloudGemMessageOfTheDayRequestBus")
// one of these for each function
->Event("PutAdminMessages", &CloudGemMessageOfTheDayRequestBus::Events::PutAdminMessages)
->Event("GetAdminMessages", &CloudGemMessageOfTheDayRequestBus::Events::GetAdminMessages)
;
behaviorContext->EBus<CloudGemMessageOfTheDayNotificationBus>("CloudGemMessageOfTheDayNotificationBus")
->Handler<BehaviorCloudGemMessageOfTheDayNotificationBusHandler>()
;
}
}
// Functions from the swagger definitions
void PutAdminMessages(const AZStd::string& msg_id, const MessageData& msg, CloudGemMessageOfTheDayResponseHandler* responseHandler) override
{
if (responseHandler == nullptr)
{
responseHandler = AZStd::get_pointer(m_defaultResponseHandler);
}
// create job
PutAdminMessagesRequestJob* job = PutAdminMessagesRequestJob::Create(
[responseHandler, this](PutAdminMessagesRequestJob* job)
{
// handle success
responseHandler->HandlePutAdminMessagesSuccess(job, m_entity);
},
[responseHandler, this](PutAdminMessagesRequestJob* job)
{
// handle error
responseHandler->HandlePutAdminMessagesError(job, m_entity);
}
);
job->parameters.msg = msg;
job->parameters.msg_id = msg_id;
job->Start();
}
void GetAdminMessages(const int& index, const int& count, const AZStd::string& filter, CloudGemMessageOfTheDayResponseHandler* responseHandler) override
{
if (responseHandler == nullptr)
{
responseHandler = AZStd::get_pointer(m_defaultResponseHandler);
}
// create job
GetAdminMessagesRequestJob* job = GetAdminMessagesRequestJob::Create(
[responseHandler, this](GetAdminMessagesRequestJob* job)
{
// handle success
responseHandler->HandleGetAdminMessagesSuccess(job, m_entity);
},
[responseHandler, this](GetAdminMessagesRequestJob* job)
{
// handle error
responseHandler->HandleGetAdminMessagesError(job, m_entity);
}
);
job->parameters.index = index;
job->parameters.count = count;
job->parameters.filter = filter;
job->Start();
}
};
bool MessageData::OnJsonKey(const char* key, CloudGemFramework::JsonReader& reader)
{
if (strcmp(key, "priority") == 0) return reader.Accept(priority);
if (strcmp(key, "message") == 0) return reader.Accept(message);
if (strcmp(key, "endTime") == 0) return reader.Accept(endTime);
if (strcmp(key, "startTime") == 0) return reader.Accept(startTime);
return reader.Ignore();
}
void MessageData::Reflect(AZ::ReflectContext* reflection)
{
AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(reflection);
if (serializeContext)
{
serializeContext->Class<MessageData>()
->Version(1);
}
AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(reflection);
if (behaviorContext)
{
behaviorContext->Class<MessageData>("CloudGemMessageOfTheDay_MessageData")
->Attribute(AZ::Script::Attributes::Storage, AZ::Script::Attributes::StorageType::Value)
->Property("priority", BehaviorValueProperty(&MessageData::priority))
->Property("message", BehaviorValueProperty(&MessageData::message))
->Property("endTime", BehaviorValueProperty(&MessageData::endTime))
->Property("startTime", BehaviorValueProperty(&MessageData::startTime))
;
}
}
bool PutAdminMessagesReturnType::OnJsonKey(const char* key, CloudGemFramework::JsonReader& reader)
{
return reader.Ignore();
}
void PutAdminMessagesReturnType::Reflect(AZ::ReflectContext* reflection)
{
AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(reflection);
if (serializeContext)
{
serializeContext->Class<PutAdminMessagesReturnType>()
->Version(1);
}
AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(reflection);
if (behaviorContext)
{
behaviorContext->Class<PutAdminMessagesReturnType>("CloudGemMessageOfTheDay_PutAdminMessagesReturnType")
->Attribute(AZ::Script::Attributes::Storage, AZ::Script::Attributes::StorageType::Value)
;
}
}
bool DetailedMessageData::OnJsonKey(const char* key, CloudGemFramework::JsonReader& reader)
{
if (strcmp(key, "priority") == 0) return reader.Accept(priority);
if (strcmp(key, "message") == 0) return reader.Accept(message);
if (strcmp(key, "endTime") == 0) return reader.Accept(endTime);
if (strcmp(key, "UniqueMsgID") == 0) return reader.Accept(UniqueMsgID);
if (strcmp(key, "startTime") == 0) return reader.Accept(startTime);
return reader.Ignore();
}
void DetailedMessageData::Reflect(AZ::ReflectContext* reflection)
{
AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(reflection);
if (serializeContext)
{
serializeContext->Class<DetailedMessageData>()->Version(1);
}
AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(reflection);
if (behaviorContext)
{
behaviorContext->Class<DetailedMessageData>("CloudGemMessageOfTheDay_DetailedMessageData")
->Attribute(AZ::Script::Attributes::Storage, AZ::Script::Attributes::StorageType::Value)
->Property("priority", BehaviorValueProperty(&DetailedMessageData::priority))
->Property("message", BehaviorValueProperty(&DetailedMessageData::message))
->Property("endTime", BehaviorValueProperty(&DetailedMessageData::endTime))
->Property("UniqueMsgID", BehaviorValueProperty(&DetailedMessageData::UniqueMsgID))
->Property("startTime", BehaviorValueProperty(&DetailedMessageData::startTime))
;
}
}
bool DetailedMessageList::OnJsonKey(const char* key, CloudGemFramework::JsonReader& reader)
{
if (strcmp(key, "list") == 0) return reader.Accept(list);
return reader.Ignore();
}
void DetailedMessageList::Reflect(AZ::ReflectContext* reflection)
{
AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(reflection);
if (serializeContext)
{
serializeContext->Class<DetailedMessageList>()->Version(1);
}
AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(reflection);
if (behaviorContext)
{
behaviorContext->Class<DetailedMessageList>("CloudGemMessageOfTheDay_DetailedMessageList")
->Attribute(AZ::Script::Attributes::Storage, AZ::Script::Attributes::StorageType::Value)
->Property("list", BehaviorValueProperty(&DetailedMessageList::list))
;
}
}
} // ServiceAPI
} // CloudGemMessageOfTheDay
Examining the Generated Game Client Code
The following table provides additional information for the generated game client code example in the previous section. The line numbers indicate the location in the code that the comments refer to.
Line Number | Description |
---|---|
24, 25 | The C++ namespace for the API. This is always <resource-group-name>::ServiceApi. |
56, 75, 110, 124 | The PutAdminMessageReturnType struct contains the PUT operation’s return data as defined by the swagger file. In this case, it is an empty object and has no properties. |
67, 92, 112, 137 | The WriteJson method is generated to handle the serialization of PutAdminMessageReturnType objects to JSON text format. JSON format is required for the data to be sent to the service. A similar function is generated for each of the type definitions in the swagger.json file. |
150 | The CLOUD_GEM_SERVICE macro defines a class that provides information that is common to all of the service’s requests. |
152 | The Configure function is called when the generated component is initialized. You can add code to this function to change the default configuration for the service. For example, the following code increases the timeout for GetServiceStatus requests.void Configure()If you regenerate the client, your changes to the Configure method are lost. |
157, 202 | A Request class such as PutAdminMessagesRequest is generated for each of the operations defined in the swagger.json file. This class encapsulates the HTTP method and path that are used to make the request. The Parameters struct in the class defines the fields for each of the request’s parameters that are specified by the swagger file. |
200, 240 | The Lumberyard job system executes API requests asynchronously. This work is performed by the CloudGemFramework::ServiceRequestJob class and specialized by the PutAdminMessagesRequest class declared previously. The C++ using statement creates an alias for that type. |
243 | Defines the CloudGemMessageOfTheDayNotifications EBus that signals when a request has completed. Both a success and an error notification method are defined for each operation specified in the swagger.json file. |
291 | Defines a handler (BehaviorCloudGemMessageOfTheDayNotificationBusHandler) for the notification EBus that forwards notifications to Lua code. |
340 | Defines an EBus (CloudGemMessageOfTheDayRequestBus) that initiates requests. |
344 | Defines a class (CloudGemMessageOfTheDayResponseHandler) that handles responses. By default, responses are dispatched to the notification EBus previously defined. |
374 | Defines a client component (CloudGemMessageOfTheDayClientComponent) that uses the using the request job classes PutAdminMessagesRequest (line 157) and GetAdminMessagesRequest (line 202) to implement the request EBus handler BehaviorCloudGemMessageOfTheDayNotificationBusHandler (line 291). |