diff --git a/redfish-core/include/redfish.hpp b/redfish-core/include/redfish.hpp
index db58d60..7429b77 100644
--- a/redfish-core/include/redfish.hpp
+++ b/redfish-core/include/redfish.hpp
@@ -67,96 +67,94 @@
         nodes.emplace_back(std::make_unique<AccountsCollection>(app));
         nodes.emplace_back(std::make_unique<ManagerAccount>(app));
         nodes.emplace_back(std::make_unique<SessionCollection>(app));
-        nodes.emplace_back(std::make_unique<Roles>(app));
-        nodes.emplace_back(std::make_unique<RoleCollection>(app));
-        nodes.emplace_back(std::make_unique<ServiceRoot>(app));
-        nodes.emplace_back(std::make_unique<NetworkProtocol>(app));
+        requestRoutesRoles(app);
+        requestRoutesRoleCollection(app);
+        requestRoutesServiceRoot(app);
+        requestRoutesNetworkProtocol(app);
         nodes.emplace_back(std::make_unique<SessionService>(app));
         nodes.emplace_back(std::make_unique<EthernetCollection>(app));
         nodes.emplace_back(std::make_unique<EthernetInterface>(app));
-        nodes.emplace_back(std::make_unique<Thermal>(app));
-        nodes.emplace_back(std::make_unique<ManagerCollection>(app));
-        nodes.emplace_back(std::make_unique<Manager>(app));
-        nodes.emplace_back(std::make_unique<ManagerResetAction>(app));
-        nodes.emplace_back(std::make_unique<ManagerResetActionInfo>(app));
-        nodes.emplace_back(std::make_unique<ManagerResetToDefaultsAction>(app));
-        nodes.emplace_back(std::make_unique<Power>(app));
-        nodes.emplace_back(std::make_unique<ChassisCollection>(app));
-        nodes.emplace_back(std::make_unique<Chassis>(app));
-        nodes.emplace_back(std::make_unique<ChassisResetAction>(app));
-        nodes.emplace_back(std::make_unique<ChassisResetActionInfo>(app));
-        nodes.emplace_back(std::make_unique<UpdateService>(app));
-        nodes.emplace_back(std::make_unique<StorageCollection>(app));
-        nodes.emplace_back(std::make_unique<Storage>(app));
-        nodes.emplace_back(std::make_unique<Drive>(app));
+        requestRoutesThermal(app);
+        requestRoutesManagerCollection(app);
+        requestRoutesManager(app);
+        requestRoutesManagerResetAction(app);
+        requestRoutesManagerResetActionInfo(app);
+        requestRoutesManagerResetToDefaultsAction(app);
+        requestRoutesPower(app);
+        requestRoutesChassisCollection(app);
+        requestRoutesChassis(app);
+        requestRoutesChassisResetAction(app);
+        requestRoutesChassisResetActionInfo(app);
+        requestRoutesUpdateService(app);
+        requestRoutesStorageCollection(app);
+        requestRoutesStorage(app);
+        requestRoutesDrive(app);
 #ifdef BMCWEB_INSECURE_ENABLE_REDFISH_FW_TFTP_UPDATE
-        nodes.emplace_back(
-            std::make_unique<UpdateServiceActionsSimpleUpdate>(app));
+        requestRoutesUpdateServiceActionsSimpleUpdate(app);
 #endif
-        nodes.emplace_back(std::make_unique<SoftwareInventoryCollection>(app));
-        nodes.emplace_back(std::make_unique<SoftwareInventory>(app));
+        requestRoutesSoftwareInventoryCollection(app);
+        requestRoutesSoftwareInventory(app);
         nodes.emplace_back(
             std::make_unique<VlanNetworkInterfaceCollection>(app));
         nodes.emplace_back(std::make_unique<VlanNetworkInterface>(app));
 
-        nodes.emplace_back(std::make_unique<SystemLogServiceCollection>(app));
-        nodes.emplace_back(std::make_unique<EventLogService>(app));
+        requestRoutesSystemLogServiceCollection(app);
+        requestRoutesEventLogService(app);
 
-        nodes.emplace_back(std::make_unique<PostCodesLogService>(app));
-        nodes.emplace_back(std::make_unique<PostCodesClear>(app));
-        nodes.emplace_back(std::make_unique<PostCodesEntry>(app));
-        nodes.emplace_back(std::make_unique<PostCodesEntryCollection>(app));
+        requestRoutesPostCodesLogService(app);
+        requestRoutesPostCodesClear(app);
+        requestRoutesPostCodesEntry(app);
+        requestRoutesPostCodesEntryCollection(app);
 
 #ifdef BMCWEB_ENABLE_REDFISH_DUMP_LOG
-        nodes.emplace_back(std::make_unique<SystemDumpService>(app));
-        nodes.emplace_back(std::make_unique<SystemDumpEntryCollection>(app));
-        nodes.emplace_back(std::make_unique<SystemDumpEntry>(app));
-        nodes.emplace_back(std::make_unique<SystemDumpCreate>(app));
-        nodes.emplace_back(std::make_unique<SystemDumpClear>(app));
+        requestRoutesSystemDumpService(app);
+        requestRoutesSystemDumpEntryCollection(app);
+        requestRoutesSystemDumpEntry(app);
+        requestRoutesSystemDumpCreate(app);
+        requestRoutesSystemDumpClear(app);
 
-        nodes.emplace_back(std::make_unique<BMCDumpService>(app));
-        nodes.emplace_back(std::make_unique<BMCDumpEntryCollection>(app));
-        nodes.emplace_back(std::make_unique<BMCDumpEntry>(app));
-        nodes.emplace_back(std::make_unique<BMCDumpCreate>(app));
-        nodes.emplace_back(std::make_unique<BMCDumpClear>(app));
+        requestRoutesBMCDumpService(app);
+        requestRoutesBMCDumpEntryCollection(app);
+        requestRoutesBMCDumpEntry(app);
+        requestRoutesBMCDumpCreate(app);
+        requestRoutesBMCDumpClear(app);
 #endif
 
 #ifndef BMCWEB_ENABLE_REDFISH_DBUS_LOG_ENTRIES
-        nodes.emplace_back(
-            std::make_unique<JournalEventLogEntryCollection>(app));
-        nodes.emplace_back(std::make_unique<JournalEventLogEntry>(app));
-        nodes.emplace_back(std::make_unique<JournalEventLogClear>(app));
+        requestRoutesJournalEventLogEntryCollection(app);
+        requestRoutesJournalEventLogEntry(app);
+        requestRoutesJournalEventLogClear(app);
 #endif
 
-        nodes.emplace_back(std::make_unique<BMCLogServiceCollection>(app));
+        requestRoutesBMCLogServiceCollection(app);
 #ifdef BMCWEB_ENABLE_REDFISH_BMC_JOURNAL
-        nodes.emplace_back(std::make_unique<BMCJournalLogService>(app));
-        nodes.emplace_back(std::make_unique<BMCJournalLogEntryCollection>(app));
-        nodes.emplace_back(std::make_unique<BMCJournalLogEntry>(app));
+        requestRoutesBMCJournalLogService(app);
+        requestRoutesBMCJournalLogEntryCollection(app);
+        requestRoutesBMCJournalLogEntry(app);
 #endif
 
 #ifdef BMCWEB_ENABLE_REDFISH_CPU_LOG
-        nodes.emplace_back(std::make_unique<CrashdumpService>(app));
-        nodes.emplace_back(std::make_unique<CrashdumpEntryCollection>(app));
-        nodes.emplace_back(std::make_unique<CrashdumpEntry>(app));
-        nodes.emplace_back(std::make_unique<CrashdumpFile>(app));
-        nodes.emplace_back(std::make_unique<CrashdumpClear>(app));
-        nodes.emplace_back(std::make_unique<CrashdumpCollect>(app));
+        requestRoutesCrashdumpService(app);
+        requestRoutesCrashdumpEntryCollection(app);
+        requestRoutesCrashdumpEntry(app);
+        requestRoutesCrashdumpFile(app);
+        requestRoutesCrashdumpClear(app);
+        requestRoutesCrashdumpCollect(app);
 #endif // BMCWEB_ENABLE_REDFISH_CPU_LOG
 
-        nodes.emplace_back(std::make_unique<ProcessorCollection>(app));
-        nodes.emplace_back(std::make_unique<Processor>(app));
-        nodes.emplace_back(std::make_unique<OperatingConfigCollection>(app));
-        nodes.emplace_back(std::make_unique<OperatingConfig>(app));
-        nodes.emplace_back(std::make_unique<MemoryCollection>(app));
-        nodes.emplace_back(std::make_unique<Memory>(app));
+        requestRoutesProcessorCollection(app);
+        requestRoutesProcessor(app);
+        requestRoutesOperatingConfigCollection(app);
+        requestRoutesOperatingConfig(app);
+        requestRoutesMemoryCollection(app);
+        requestRoutesMemory(app);
 
-        nodes.emplace_back(std::make_unique<SystemsCollection>(app));
-        nodes.emplace_back(std::make_unique<Systems>(app));
-        nodes.emplace_back(std::make_unique<SystemActionsReset>(app));
-        nodes.emplace_back(std::make_unique<SystemResetActionInfo>(app));
-        nodes.emplace_back(std::make_unique<BiosService>(app));
-        nodes.emplace_back(std::make_unique<BiosReset>(app));
+        requestRoutesSystemsCollection(app);
+        requestRoutesSystems(app);
+        requestRoutesSystemActionsReset(app);
+        requestRoutesSystemResetActionInfo(app);
+        requestRoutesBiosService(app);
+        requestRoutesBiosReset(app);
 #ifdef BMCWEB_ENABLE_VM_NBDPROXY
         nodes.emplace_back(std::make_unique<VirtualMedia>(app));
         nodes.emplace_back(std::make_unique<VirtualMediaCollection>(app));
@@ -165,58 +163,51 @@
         nodes.emplace_back(std::make_unique<VirtualMediaActionEjectMedia>(app));
 #endif // BMCWEB_ENABLE_VM_NBDPROXY
 #ifdef BMCWEB_ENABLE_REDFISH_DBUS_LOG_ENTRIES
-        nodes.emplace_back(std::make_unique<DBusLogServiceActionsClear>(app));
-        nodes.emplace_back(std::make_unique<DBusEventLogEntryCollection>(app));
-        nodes.emplace_back(std::make_unique<DBusEventLogEntry>(app));
-        nodes.emplace_back(std::make_unique<DBusEventLogEntryDownload>(app));
+        requestRoutesDBusLogServiceActionsClear(app);
+        requestRoutesDBusEventLogEntryCollection(app);
+        requestRoutesDBusEventLogEntry(app);
+        requestRoutesDBusEventLogEntryDownload(app);
 #endif
 
-        nodes.emplace_back(
-            std::make_unique<MessageRegistryFileCollection>(app));
-        nodes.emplace_back(std::make_unique<MessageRegistryFile>(app));
-        nodes.emplace_back(std::make_unique<MessageRegistry>(app));
-        nodes.emplace_back(std::make_unique<CertificateService>(app));
-        nodes.emplace_back(
-            std::make_unique<CertificateActionsReplaceCertificate>(app));
-        nodes.emplace_back(std::make_unique<CertificateLocations>(app));
-        nodes.emplace_back(std::make_unique<HTTPSCertificateCollection>(app));
-        nodes.emplace_back(std::make_unique<HTTPSCertificate>(app));
-        nodes.emplace_back(std::make_unique<LDAPCertificateCollection>(app));
-        nodes.emplace_back(std::make_unique<LDAPCertificate>(app));
-        nodes.emplace_back(std::make_unique<CertificateActionGenerateCSR>(app));
-        nodes.emplace_back(
-            std::make_unique<TrustStoreCertificateCollection>(app));
-        nodes.emplace_back(std::make_unique<TrustStoreCertificate>(app));
-        nodes.emplace_back(std::make_unique<SystemPCIeFunctionCollection>(app));
-        nodes.emplace_back(std::make_unique<SystemPCIeFunction>(app));
-        nodes.emplace_back(std::make_unique<SystemPCIeDeviceCollection>(app));
-        nodes.emplace_back(std::make_unique<SystemPCIeDevice>(app));
+        requestRoutesMessageRegistryFileCollection(app);
+        requestRoutesMessageRegistryFile(app);
+        requestRoutesMessageRegistry(app);
 
-        nodes.emplace_back(std::make_unique<SensorCollection>(app));
-        nodes.emplace_back(std::make_unique<Sensor>(app));
+        requestRoutesCertificateService(app);
+        requestRoutesCertificateActionGenerateCSR(app);
+        requestRoutesCertificateActionsReplaceCertificate(app);
+        requestRoutesHTTPSCertificate(app);
+        requestRoutesHTTPSCertificateCollection(app);
+        requestRoutesCertificateLocations(app);
+        requestRoutesLDAPCertificateCollection(app);
+        requestRoutesLDAPCertificate(app);
+        requestRoutesTrustStoreCertificateCollection(app);
+        requestRoutesTrustStoreCertificate(app);
 
-        nodes.emplace_back(std::make_unique<TaskMonitor>(app));
-        nodes.emplace_back(std::make_unique<TaskService>(app));
-        nodes.emplace_back(std::make_unique<TaskCollection>(app));
-        nodes.emplace_back(std::make_unique<Task>(app));
-        nodes.emplace_back(std::make_unique<EventService>(app));
-        nodes.emplace_back(std::make_unique<EventDestinationCollection>(app));
-        nodes.emplace_back(std::make_unique<EventDestination>(app));
-        nodes.emplace_back(std::make_unique<SubmitTestEvent>(app));
+        requestRoutesSystemPCIeFunctionCollection(app);
+        requestRoutesSystemPCIeFunction(app);
+        requestRoutesSystemPCIeDeviceCollection(app);
+        requestRoutesSystemPCIeDevice(app);
 
-        nodes.emplace_back(
-            std::make_unique<HypervisorInterfaceCollection>(app));
-        nodes.emplace_back(std::make_unique<HypervisorInterface>(app));
-        nodes.emplace_back(std::make_unique<HypervisorSystem>(app));
-        nodes.emplace_back(std::make_unique<HypervisorActionsReset>(app));
-        nodes.emplace_back(std::make_unique<HypervisorResetActionInfo>(app));
+        requestRoutesSensorCollection(app);
+        requestRoutesSensor(app);
 
-        nodes.emplace_back(std::make_unique<TelemetryService>(app));
-        nodes.emplace_back(
-            std::make_unique<MetricReportDefinitionCollection>(app));
-        nodes.emplace_back(std::make_unique<MetricReportDefinition>(app));
-        nodes.emplace_back(std::make_unique<MetricReportCollection>(app));
-        nodes.emplace_back(std::make_unique<MetricReport>(app));
+        requestRoutesTaskMonitor(app);
+        requestRoutesTaskService(app);
+        requestRoutesTaskCollection(app);
+        requestRoutesTask(app);
+        requestRoutesEventService(app);
+        requestRoutesEventDestinationCollection(app);
+        requestRoutesEventDestination(app);
+        requestRoutesSubmitTestEvent(app);
+
+        requestRoutesHypervisorSystems(app);
+
+        requestRoutesTelemetryService(app);
+        requestRoutesMetricReportDefinitionCollection(app);
+        requestRoutesMetricReportDefinition(app);
+        requestRoutesMetricReportCollection(app);
+        requestRoutesMetricReport(app);
 
         for (const auto& node : nodes)
         {
diff --git a/redfish-core/lib/account_service.hpp b/redfish-core/lib/account_service.hpp
index cedea22..2e81104 100644
--- a/redfish-core/lib/account_service.hpp
+++ b/redfish-core/lib/account_service.hpp
@@ -16,6 +16,7 @@
 #pragma once
 #include "node.hpp"
 
+#include <app.hpp>
 #include <dbus_utility.hpp>
 #include <error_messages.hpp>
 #include <openbmc_dbus_rest.hpp>
diff --git a/redfish-core/lib/bios.hpp b/redfish-core/lib/bios.hpp
index 0917cc7..de6f9a1 100644
--- a/redfish-core/lib/bios.hpp
+++ b/redfish-core/lib/bios.hpp
@@ -1,75 +1,62 @@
 #pragma once
 
-#include "node.hpp"
-
+#include <app.hpp>
 #include <utils/fw_utils.hpp>
 namespace redfish
 {
 /**
  * BiosService class supports handle get method for bios.
  */
-class BiosService : public Node
+inline void requestRoutesBiosService(App& app)
 {
-  public:
-    BiosService(App& app) : Node(app, "/redfish/v1/Systems/system/Bios/")
-    {
-        entityPrivileges = {{boost::beast::http::verb::get, {{"Login"}}}};
-    }
+    BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/Bios/")
+        .privileges({"Login"})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                asyncResp->res.jsonValue["@odata.id"] =
+                    "/redfish/v1/Systems/system/Bios";
+                asyncResp->res.jsonValue["@odata.type"] = "#Bios.v1_1_0.Bios";
+                asyncResp->res.jsonValue["Name"] = "BIOS Configuration";
+                asyncResp->res.jsonValue["Description"] =
+                    "BIOS Configuration Service";
+                asyncResp->res.jsonValue["Id"] = "BIOS";
+                asyncResp->res.jsonValue["Actions"]["#Bios.ResetBios"] = {
+                    {"target",
+                     "/redfish/v1/Systems/system/Bios/Actions/Bios.ResetBios"}};
 
-  private:
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&, const std::vector<std::string>&) override
-    {
-        asyncResp->res.jsonValue["@odata.id"] =
-            "/redfish/v1/Systems/system/Bios";
-        asyncResp->res.jsonValue["@odata.type"] = "#Bios.v1_1_0.Bios";
-        asyncResp->res.jsonValue["Name"] = "BIOS Configuration";
-        asyncResp->res.jsonValue["Description"] = "BIOS Configuration Service";
-        asyncResp->res.jsonValue["Id"] = "BIOS";
-        asyncResp->res.jsonValue["Actions"]["#Bios.ResetBios"] = {
-            {"target",
-             "/redfish/v1/Systems/system/Bios/Actions/Bios.ResetBios"}};
-
-        // Get the ActiveSoftwareImage and SoftwareImages
-        fw_util::populateFirmwareInformation(asyncResp, fw_util::biosPurpose,
-                                             "", true);
-    }
-};
+                // Get the ActiveSoftwareImage and SoftwareImages
+                fw_util::populateFirmwareInformation(
+                    asyncResp, fw_util::biosPurpose, "", true);
+            });
+}
 /**
  * BiosReset class supports handle POST method for Reset bios.
  * The class retrieves and sends data directly to D-Bus.
+ *
+ * Function handles POST method request.
+ * Analyzes POST body message before sends Reset request data to D-Bus.
  */
-class BiosReset : public Node
+
+inline void requestRoutesBiosReset(App& app)
 {
-  public:
-    BiosReset(App& app) :
-        Node(app, "/redfish/v1/Systems/system/Bios/Actions/Bios.ResetBios/")
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-    }
-
-  private:
-    /**
-     * Function handles POST method request.
-     * Analyzes POST body message before sends Reset request data to D-Bus.
-     */
-    void doPost(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                const crow::Request&, const std::vector<std::string>&) override
-    {
-
-        crow::connections::systemBus->async_method_call(
-            [asyncResp](const boost::system::error_code ec) {
-                if (ec)
-                {
-                    BMCWEB_LOG_ERROR << "Failed to reset bios: " << ec;
-                    messages::internalError(asyncResp->res);
-                    return;
-                }
-            },
-            "org.open_power.Software.Host.Updater",
-            "/xyz/openbmc_project/software",
-            "xyz.openbmc_project.Common.FactoryReset", "Reset");
-    }
-};
+    BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/Bios/Actions/Bios.ResetBios/")
+        .privileges({"ConfigureManager"})
+        .methods(boost::beast::http::verb::post)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                crow::connections::systemBus->async_method_call(
+                    [asyncResp](const boost::system::error_code ec) {
+                        if (ec)
+                        {
+                            BMCWEB_LOG_ERROR << "Failed to reset bios: " << ec;
+                            messages::internalError(asyncResp->res);
+                            return;
+                        }
+                    },
+                    "org.open_power.Software.Host.Updater",
+                    "/xyz/openbmc_project/software",
+                    "xyz.openbmc_project.Common.FactoryReset", "Reset");
+            });
+}
 } // namespace redfish
diff --git a/redfish-core/lib/certificate_service.hpp b/redfish-core/lib/certificate_service.hpp
index 0e53571..0e26a86 100644
--- a/redfish-core/lib/certificate_service.hpp
+++ b/redfish-core/lib/certificate_service.hpp
@@ -1,7 +1,6 @@
 #pragma once
 
-#include "node.hpp"
-
+#include <app.hpp>
 #include <boost/convert.hpp>
 #include <boost/convert/strtol.hpp>
 
@@ -34,47 +33,42 @@
  * actions available to manage certificates and links to where certificates
  * are installed.
  */
-class CertificateService : public Node
-{
-  public:
-    CertificateService(App& app) : Node(app, "/redfish/v1/CertificateService/")
-    {
-        // TODO: Issue#61 No entries are available for Certificate
-        // service at https://www.dmtf.org/standards/redfish
-        // "redfish standard registries". Need to modify after DMTF
-        // publish Privilege details for certificate service
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
-    }
 
-  private:
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&, const std::vector<std::string>&) override
-    {
-        asyncResp->res.jsonValue = {
-            {"@odata.type", "#CertificateService.v1_0_0.CertificateService"},
-            {"@odata.id", "/redfish/v1/CertificateService"},
-            {"Id", "CertificateService"},
-            {"Name", "Certificate Service"},
-            {"Description", "Actions available to manage certificates"}};
-        asyncResp->res.jsonValue["CertificateLocations"] = {
-            {"@odata.id",
-             "/redfish/v1/CertificateService/CertificateLocations"}};
-        asyncResp->res
-            .jsonValue["Actions"]["#CertificateService.ReplaceCertificate"] = {
-            {"target", "/redfish/v1/CertificateService/Actions/"
-                       "CertificateService.ReplaceCertificate"},
-            {"CertificateType@Redfish.AllowableValues", {"PEM"}}};
-        asyncResp->res.jsonValue["Actions"]["#CertificateService.GenerateCSR"] =
-            {{"target", "/redfish/v1/CertificateService/Actions/"
-                        "CertificateService.GenerateCSR"}};
-    }
-}; // CertificateService
+// TODO: Issue#61 No entries are available for Certificate
+// service at https://www.dmtf.org/standards/redfish
+// "redfish standard registries". Need to modify after DMTF
+// publish Privilege details for certificate service
+
+inline void requestRoutesCertificateService(App& app)
+{
+    BMCWEB_ROUTE(app, "/redfish/v1/CertificateService/")
+        .privileges({"Login"})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                asyncResp->res.jsonValue = {
+                    {"@odata.type",
+                     "#CertificateService.v1_0_0.CertificateService"},
+                    {"@odata.id", "/redfish/v1/CertificateService"},
+                    {"Id", "CertificateService"},
+                    {"Name", "Certificate Service"},
+                    {"Description",
+                     "Actions available to manage certificates"}};
+                asyncResp->res.jsonValue["CertificateLocations"] = {
+                    {"@odata.id",
+                     "/redfish/v1/CertificateService/CertificateLocations"}};
+                asyncResp->res
+                    .jsonValue["Actions"]
+                              ["#CertificateService.ReplaceCertificate"] = {
+                    {"target", "/redfish/v1/CertificateService/Actions/"
+                               "CertificateService.ReplaceCertificate"},
+                    {"CertificateType@Redfish.AllowableValues", {"PEM"}}};
+                asyncResp->res
+                    .jsonValue["Actions"]["#CertificateService.GenerateCSR"] = {
+                    {"target", "/redfish/v1/CertificateService/Actions/"
+                               "CertificateService.GenerateCSR"}};
+            });
+} // requestRoutesCertificateService
 
 /**
  * @brief Find the ID specified in the URL
@@ -230,259 +224,259 @@
 /**
  * Action to Generate CSR
  */
-class CertificateActionGenerateCSR : public Node
+inline void requestRoutesCertificateActionGenerateCSR(App& app)
 {
-  public:
-    CertificateActionGenerateCSR(App& app) :
-        Node(app, "/redfish/v1/CertificateService/Actions/"
-                  "CertificateService.GenerateCSR/")
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
-    }
+    BMCWEB_ROUTE(app, "/redfish/v1/CertificateService/Actions/"
+                      "CertificateService.GenerateCSR/")
+        .privileges({"ConfigureComponents"})
+        .methods(boost::beast::http::verb::post)(
+            [](const crow::Request& req,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                static const int rsaKeyBitLength = 2048;
 
-  private:
-    void doPost(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                const crow::Request& req,
-                const std::vector<std::string>&) override
-    {
-        static const int rsaKeyBitLength = 2048;
+                // Required parameters
+                std::string city;
+                std::string commonName;
+                std::string country;
+                std::string organization;
+                std::string organizationalUnit;
+                std::string state;
+                nlohmann::json certificateCollection;
 
-        // Required parameters
-        std::string city;
-        std::string commonName;
-        std::string country;
-        std::string organization;
-        std::string organizationalUnit;
-        std::string state;
-        nlohmann::json certificateCollection;
+                // Optional parameters
+                std::optional<std::vector<std::string>> optAlternativeNames =
+                    std::vector<std::string>();
+                std::optional<std::string> optContactPerson = "";
+                std::optional<std::string> optChallengePassword = "";
+                std::optional<std::string> optEmail = "";
+                std::optional<std::string> optGivenName = "";
+                std::optional<std::string> optInitials = "";
+                std::optional<int64_t> optKeyBitLength = rsaKeyBitLength;
+                std::optional<std::string> optKeyCurveId = "secp384r1";
+                std::optional<std::string> optKeyPairAlgorithm = "EC";
+                std::optional<std::vector<std::string>> optKeyUsage =
+                    std::vector<std::string>();
+                std::optional<std::string> optSurname = "";
+                std::optional<std::string> optUnstructuredName = "";
+                if (!json_util::readJson(
+                        req, asyncResp->res, "City", city, "CommonName",
+                        commonName, "ContactPerson", optContactPerson,
+                        "Country", country, "Organization", organization,
+                        "OrganizationalUnit", organizationalUnit, "State",
+                        state, "CertificateCollection", certificateCollection,
+                        "AlternativeNames", optAlternativeNames,
+                        "ChallengePassword", optChallengePassword, "Email",
+                        optEmail, "GivenName", optGivenName, "Initials",
+                        optInitials, "KeyBitLength", optKeyBitLength,
+                        "KeyCurveId", optKeyCurveId, "KeyPairAlgorithm",
+                        optKeyPairAlgorithm, "KeyUsage", optKeyUsage, "Surname",
+                        optSurname, "UnstructuredName", optUnstructuredName))
+                {
+                    return;
+                }
 
-        // Optional parameters
-        std::optional<std::vector<std::string>> optAlternativeNames =
-            std::vector<std::string>();
-        std::optional<std::string> optContactPerson = "";
-        std::optional<std::string> optChallengePassword = "";
-        std::optional<std::string> optEmail = "";
-        std::optional<std::string> optGivenName = "";
-        std::optional<std::string> optInitials = "";
-        std::optional<int64_t> optKeyBitLength = rsaKeyBitLength;
-        std::optional<std::string> optKeyCurveId = "secp384r1";
-        std::optional<std::string> optKeyPairAlgorithm = "EC";
-        std::optional<std::vector<std::string>> optKeyUsage =
-            std::vector<std::string>();
-        std::optional<std::string> optSurname = "";
-        std::optional<std::string> optUnstructuredName = "";
-        if (!json_util::readJson(
-                req, asyncResp->res, "City", city, "CommonName", commonName,
-                "ContactPerson", optContactPerson, "Country", country,
-                "Organization", organization, "OrganizationalUnit",
-                organizationalUnit, "State", state, "CertificateCollection",
-                certificateCollection, "AlternativeNames", optAlternativeNames,
-                "ChallengePassword", optChallengePassword, "Email", optEmail,
-                "GivenName", optGivenName, "Initials", optInitials,
-                "KeyBitLength", optKeyBitLength, "KeyCurveId", optKeyCurveId,
-                "KeyPairAlgorithm", optKeyPairAlgorithm, "KeyUsage",
-                optKeyUsage, "Surname", optSurname, "UnstructuredName",
-                optUnstructuredName))
-        {
-            return;
-        }
+                // bmcweb has no way to store or decode a private key challenge
+                // password, which will likely cause bmcweb to crash on startup
+                // if this is not set on a post so not allowing the user to set
+                // value
+                if (*optChallengePassword != "")
+                {
+                    messages::actionParameterNotSupported(
+                        asyncResp->res, "GenerateCSR", "ChallengePassword");
+                    return;
+                }
 
-        // bmcweb has no way to store or decode a private key challenge
-        // password, which will likely cause bmcweb to crash on startup if this
-        // is not set on a post so not allowing the user to set value
-        if (*optChallengePassword != "")
-        {
-            messages::actionParameterNotSupported(asyncResp->res, "GenerateCSR",
-                                                  "ChallengePassword");
-            return;
-        }
+                std::string certURI;
+                if (!redfish::json_util::readJson(certificateCollection,
+                                                  asyncResp->res, "@odata.id",
+                                                  certURI))
+                {
+                    return;
+                }
 
-        std::string certURI;
-        if (!redfish::json_util::readJson(certificateCollection, asyncResp->res,
-                                          "@odata.id", certURI))
-        {
-            return;
-        }
+                std::string objectPath;
+                std::string service;
+                if (boost::starts_with(certURI,
+                                       "/redfish/v1/Managers/bmc/"
+                                       "NetworkProtocol/HTTPS/Certificates"))
+                {
+                    objectPath = certs::httpsObjectPath;
+                    service = certs::httpsServiceName;
+                }
+                else if (boost::starts_with(
+                             certURI,
+                             "/redfish/v1/AccountService/LDAP/Certificates"))
+                {
+                    objectPath = certs::ldapObjectPath;
+                    service = certs::ldapServiceName;
+                }
+                else
+                {
+                    messages::actionParameterNotSupported(
+                        asyncResp->res, "CertificateCollection", "GenerateCSR");
+                    return;
+                }
 
-        std::string objectPath;
-        std::string service;
-        if (boost::starts_with(
-                certURI,
-                "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates"))
-        {
-            objectPath = certs::httpsObjectPath;
-            service = certs::httpsServiceName;
-        }
-        else if (boost::starts_with(
-                     certURI, "/redfish/v1/AccountService/LDAP/Certificates"))
-        {
-            objectPath = certs::ldapObjectPath;
-            service = certs::ldapServiceName;
-        }
-        else
-        {
-            messages::actionParameterNotSupported(
-                asyncResp->res, "CertificateCollection", "GenerateCSR");
-            return;
-        }
+                // supporting only EC and RSA algorithm
+                if (*optKeyPairAlgorithm != "EC" &&
+                    *optKeyPairAlgorithm != "RSA")
+                {
+                    messages::actionParameterNotSupported(
+                        asyncResp->res, "KeyPairAlgorithm", "GenerateCSR");
+                    return;
+                }
 
-        // supporting only EC and RSA algorithm
-        if (*optKeyPairAlgorithm != "EC" && *optKeyPairAlgorithm != "RSA")
-        {
-            messages::actionParameterNotSupported(
-                asyncResp->res, "KeyPairAlgorithm", "GenerateCSR");
-            return;
-        }
-
-        // supporting only 2048 key bit length for RSA algorithm due to time
-        // consumed in generating private key
-        if (*optKeyPairAlgorithm == "RSA" &&
-            *optKeyBitLength != rsaKeyBitLength)
-        {
-            messages::propertyValueNotInList(asyncResp->res,
-                                             std::to_string(*optKeyBitLength),
-                                             "KeyBitLength");
-            return;
-        }
-
-        // validate KeyUsage supporting only 1 type based on URL
-        if (boost::starts_with(
-                certURI,
-                "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates"))
-        {
-            if (optKeyUsage->size() == 0)
-            {
-                optKeyUsage->push_back("ServerAuthentication");
-            }
-            else if (optKeyUsage->size() == 1)
-            {
-                if ((*optKeyUsage)[0] != "ServerAuthentication")
+                // supporting only 2048 key bit length for RSA algorithm due to
+                // time consumed in generating private key
+                if (*optKeyPairAlgorithm == "RSA" &&
+                    *optKeyBitLength != rsaKeyBitLength)
                 {
                     messages::propertyValueNotInList(
-                        asyncResp->res, (*optKeyUsage)[0], "KeyUsage");
+                        asyncResp->res, std::to_string(*optKeyBitLength),
+                        "KeyBitLength");
                     return;
                 }
-            }
-            else
-            {
-                messages::actionParameterNotSupported(
-                    asyncResp->res, "KeyUsage", "GenerateCSR");
-                return;
-            }
-        }
-        else if (boost::starts_with(
-                     certURI, "/redfish/v1/AccountService/LDAP/Certificates"))
-        {
-            if (optKeyUsage->size() == 0)
-            {
-                optKeyUsage->push_back("ClientAuthentication");
-            }
-            else if (optKeyUsage->size() == 1)
-            {
-                if ((*optKeyUsage)[0] != "ClientAuthentication")
-                {
-                    messages::propertyValueNotInList(
-                        asyncResp->res, (*optKeyUsage)[0], "KeyUsage");
-                    return;
-                }
-            }
-            else
-            {
-                messages::actionParameterNotSupported(
-                    asyncResp->res, "KeyUsage", "GenerateCSR");
-                return;
-            }
-        }
 
-        // Only allow one CSR matcher at a time so setting retry time-out and
-        // timer expiry to 10 seconds for now.
-        static const int timeOut = 10;
-        if (csrMatcher)
-        {
-            messages::serviceTemporarilyUnavailable(asyncResp->res,
-                                                    std::to_string(timeOut));
-            return;
-        }
-
-        // Make this static so it survives outside this method
-        static boost::asio::steady_timer timeout(*req.ioService);
-        timeout.expires_after(std::chrono::seconds(timeOut));
-        timeout.async_wait([asyncResp](const boost::system::error_code& ec) {
-            csrMatcher = nullptr;
-            if (ec)
-            {
-                // operation_aborted is expected if timer is canceled before
-                // completion.
-                if (ec != boost::asio::error::operation_aborted)
+                // validate KeyUsage supporting only 1 type based on URL
+                if (boost::starts_with(certURI,
+                                       "/redfish/v1/Managers/bmc/"
+                                       "NetworkProtocol/HTTPS/Certificates"))
                 {
-                    BMCWEB_LOG_ERROR << "Async_wait failed " << ec;
-                }
-                return;
-            }
-            BMCWEB_LOG_ERROR << "Timed out waiting for Generating CSR";
-            messages::internalError(asyncResp->res);
-        });
-
-        // create a matcher to wait on CSR object
-        BMCWEB_LOG_DEBUG << "create matcher with path " << objectPath;
-        std::string match("type='signal',"
-                          "interface='org.freedesktop.DBus.ObjectManager',"
-                          "path='" +
-                          objectPath +
-                          "',"
-                          "member='InterfacesAdded'");
-        csrMatcher = std::make_unique<sdbusplus::bus::match::match>(
-            *crow::connections::systemBus, match,
-            [asyncResp, service, objectPath,
-             certURI](sdbusplus::message::message& m) {
-                timeout.cancel();
-                if (m.is_method_error())
-                {
-                    BMCWEB_LOG_ERROR << "Dbus method error!!!";
-                    messages::internalError(asyncResp->res);
-                    return;
-                }
-                std::vector<std::pair<
-                    std::string, std::vector<std::pair<
-                                     std::string, std::variant<std::string>>>>>
-                    interfacesProperties;
-                sdbusplus::message::object_path csrObjectPath;
-                m.read(csrObjectPath, interfacesProperties);
-                BMCWEB_LOG_DEBUG << "CSR object added" << csrObjectPath.str;
-                for (auto& interface : interfacesProperties)
-                {
-                    if (interface.first == "xyz.openbmc_project.Certs.CSR")
+                    if (optKeyUsage->size() == 0)
                     {
-                        getCSR(asyncResp, certURI, service, objectPath,
-                               csrObjectPath.str);
-                        break;
+                        optKeyUsage->push_back("ServerAuthentication");
+                    }
+                    else if (optKeyUsage->size() == 1)
+                    {
+                        if ((*optKeyUsage)[0] != "ServerAuthentication")
+                        {
+                            messages::propertyValueNotInList(
+                                asyncResp->res, (*optKeyUsage)[0], "KeyUsage");
+                            return;
+                        }
+                    }
+                    else
+                    {
+                        messages::actionParameterNotSupported(
+                            asyncResp->res, "KeyUsage", "GenerateCSR");
+                        return;
                     }
                 }
-            });
-        crow::connections::systemBus->async_method_call(
-            [asyncResp](const boost::system::error_code& ec,
-                        const std::string&) {
-                if (ec)
+                else if (boost::starts_with(
+                             certURI,
+                             "/redfish/v1/AccountService/LDAP/Certificates"))
                 {
-                    BMCWEB_LOG_ERROR << "DBUS response error: " << ec.message();
-                    messages::internalError(asyncResp->res);
+                    if (optKeyUsage->size() == 0)
+                    {
+                        optKeyUsage->push_back("ClientAuthentication");
+                    }
+                    else if (optKeyUsage->size() == 1)
+                    {
+                        if ((*optKeyUsage)[0] != "ClientAuthentication")
+                        {
+                            messages::propertyValueNotInList(
+                                asyncResp->res, (*optKeyUsage)[0], "KeyUsage");
+                            return;
+                        }
+                    }
+                    else
+                    {
+                        messages::actionParameterNotSupported(
+                            asyncResp->res, "KeyUsage", "GenerateCSR");
+                        return;
+                    }
+                }
+
+                // Only allow one CSR matcher at a time so setting retry
+                // time-out and timer expiry to 10 seconds for now.
+                static const int timeOut = 10;
+                if (csrMatcher)
+                {
+                    messages::serviceTemporarilyUnavailable(
+                        asyncResp->res, std::to_string(timeOut));
                     return;
                 }
-            },
-            service, objectPath, "xyz.openbmc_project.Certs.CSR.Create",
-            "GenerateCSR", *optAlternativeNames, *optChallengePassword, city,
-            commonName, *optContactPerson, country, *optEmail, *optGivenName,
-            *optInitials, *optKeyBitLength, *optKeyCurveId,
-            *optKeyPairAlgorithm, *optKeyUsage, organization,
-            organizationalUnit, state, *optSurname, *optUnstructuredName);
-    }
-}; // CertificateActionGenerateCSR
+
+                // Make this static so it survives outside this method
+                static boost::asio::steady_timer timeout(*req.ioService);
+                timeout.expires_after(std::chrono::seconds(timeOut));
+                timeout.async_wait([asyncResp](
+                                       const boost::system::error_code& ec) {
+                    csrMatcher = nullptr;
+                    if (ec)
+                    {
+                        // operation_aborted is expected if timer is canceled
+                        // before completion.
+                        if (ec != boost::asio::error::operation_aborted)
+                        {
+                            BMCWEB_LOG_ERROR << "Async_wait failed " << ec;
+                        }
+                        return;
+                    }
+                    BMCWEB_LOG_ERROR << "Timed out waiting for Generating CSR";
+                    messages::internalError(asyncResp->res);
+                });
+
+                // create a matcher to wait on CSR object
+                BMCWEB_LOG_DEBUG << "create matcher with path " << objectPath;
+                std::string match(
+                    "type='signal',"
+                    "interface='org.freedesktop.DBus.ObjectManager',"
+                    "path='" +
+                    objectPath +
+                    "',"
+                    "member='InterfacesAdded'");
+                csrMatcher = std::make_unique<sdbusplus::bus::match::match>(
+                    *crow::connections::systemBus, match,
+                    [asyncResp, service, objectPath,
+                     certURI](sdbusplus::message::message& m) {
+                        timeout.cancel();
+                        if (m.is_method_error())
+                        {
+                            BMCWEB_LOG_ERROR << "Dbus method error!!!";
+                            messages::internalError(asyncResp->res);
+                            return;
+                        }
+                        std::vector<std::pair<
+                            std::string,
+                            std::vector<std::pair<std::string,
+                                                  std::variant<std::string>>>>>
+                            interfacesProperties;
+                        sdbusplus::message::object_path csrObjectPath;
+                        m.read(csrObjectPath, interfacesProperties);
+                        BMCWEB_LOG_DEBUG << "CSR object added"
+                                         << csrObjectPath.str;
+                        for (auto& interface : interfacesProperties)
+                        {
+                            if (interface.first ==
+                                "xyz.openbmc_project.Certs.CSR")
+                            {
+                                getCSR(asyncResp, certURI, service, objectPath,
+                                       csrObjectPath.str);
+                                break;
+                            }
+                        }
+                    });
+                crow::connections::systemBus->async_method_call(
+                    [asyncResp](const boost::system::error_code& ec,
+                                const std::string&) {
+                        if (ec)
+                        {
+                            BMCWEB_LOG_ERROR << "DBUS response error: "
+                                             << ec.message();
+                            messages::internalError(asyncResp->res);
+                            return;
+                        }
+                    },
+                    service, objectPath, "xyz.openbmc_project.Certs.CSR.Create",
+                    "GenerateCSR", *optAlternativeNames, *optChallengePassword,
+                    city, commonName, *optContactPerson, country, *optEmail,
+                    *optGivenName, *optInitials, *optKeyBitLength,
+                    *optKeyCurveId, *optKeyPairAlgorithm, *optKeyUsage,
+                    organization, organizationalUnit, state, *optSurname,
+                    *optUnstructuredName);
+            });
+} // requestRoutesCertificateActionGenerateCSR
 
 /**
  * @brief Parse and update Certificate Issue/Subject property
@@ -669,713 +663,656 @@
 /**
  * Action to replace an existing certificate
  */
-class CertificateActionsReplaceCertificate : public Node
+inline void requestRoutesCertificateActionsReplaceCertificate(App& app)
 {
-  public:
-    CertificateActionsReplaceCertificate(App& app) :
-        Node(app, "/redfish/v1/CertificateService/Actions/"
-                  "CertificateService.ReplaceCertificate/")
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
-    }
+    BMCWEB_ROUTE(app, "/redfish/v1/CertificateService/Actions/"
+                      "CertificateService.ReplaceCertificate/")
+        .privileges({"ConfigureComponents"})
+        .methods(
+            boost::beast::http::verb::
+                post)([](const crow::Request& req,
+                         const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+            std::string certificate;
+            nlohmann::json certificateUri;
+            std::optional<std::string> certificateType = "PEM";
 
-  private:
-    void doPost(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                const crow::Request& req,
-                const std::vector<std::string>&) override
-    {
-        std::string certificate;
-        nlohmann::json certificateUri;
-        std::optional<std::string> certificateType = "PEM";
+            if (!json_util::readJson(req, asyncResp->res, "CertificateString",
+                                     certificate, "CertificateUri",
+                                     certificateUri, "CertificateType",
+                                     certificateType))
+            {
+                BMCWEB_LOG_ERROR << "Required parameters are missing";
+                messages::internalError(asyncResp->res);
+                return;
+            }
 
-        if (!json_util::readJson(req, asyncResp->res, "CertificateString",
-                                 certificate, "CertificateUri", certificateUri,
-                                 "CertificateType", certificateType))
-        {
-            BMCWEB_LOG_ERROR << "Required parameters are missing";
-            messages::internalError(asyncResp->res);
-            return;
-        }
+            if (!certificateType)
+            {
+                // should never happen, but it never hurts to be paranoid.
+                return;
+            }
+            if (certificateType != "PEM")
+            {
+                messages::actionParameterNotSupported(
+                    asyncResp->res, "CertificateType", "ReplaceCertificate");
+                return;
+            }
 
-        if (!certificateType)
-        {
-            // should never happen, but it never hurts to be paranoid.
-            return;
-        }
-        if (certificateType != "PEM")
-        {
-            messages::actionParameterNotSupported(
-                asyncResp->res, "CertificateType", "ReplaceCertificate");
-            return;
-        }
+            std::string certURI;
+            if (!redfish::json_util::readJson(certificateUri, asyncResp->res,
+                                              "@odata.id", certURI))
+            {
+                messages::actionParameterMissing(
+                    asyncResp->res, "ReplaceCertificate", "CertificateUri");
+                return;
+            }
 
-        std::string certURI;
-        if (!redfish::json_util::readJson(certificateUri, asyncResp->res,
-                                          "@odata.id", certURI))
-        {
-            messages::actionParameterMissing(
-                asyncResp->res, "ReplaceCertificate", "CertificateUri");
-            return;
-        }
+            BMCWEB_LOG_INFO << "Certificate URI to replace" << certURI;
+            long id = getIDFromURL(certURI);
+            if (id < 0)
+            {
+                messages::actionParameterValueFormatError(
+                    asyncResp->res, certURI, "CertificateUri",
+                    "ReplaceCertificate");
+                return;
+            }
+            std::string objectPath;
+            std::string name;
+            std::string service;
+            if (boost::starts_with(certURI,
+                                   "/redfish/v1/Managers/bmc/NetworkProtocol/"
+                                   "HTTPS/Certificates/"))
+            {
+                objectPath = std::string(certs::httpsObjectPath) + "/" +
+                             std::to_string(id);
+                name = "HTTPS certificate";
+                service = certs::httpsServiceName;
+            }
+            else if (boost::starts_with(
+                         certURI,
+                         "/redfish/v1/AccountService/LDAP/Certificates/"))
+            {
+                objectPath = std::string(certs::ldapObjectPath) + "/" +
+                             std::to_string(id);
+                name = "LDAP certificate";
+                service = certs::ldapServiceName;
+            }
+            else if (boost::starts_with(
+                         certURI,
+                         "/redfish/v1/Managers/bmc/Truststore/Certificates/"))
+            {
+                objectPath = std::string(certs::authorityObjectPath) + "/" +
+                             std::to_string(id);
+                name = "TrustStore certificate";
+                service = certs::authorityServiceName;
+            }
+            else
+            {
+                messages::actionParameterNotSupported(
+                    asyncResp->res, "CertificateUri", "ReplaceCertificate");
+                return;
+            }
 
-        BMCWEB_LOG_INFO << "Certificate URI to replace" << certURI;
-        long id = getIDFromURL(certURI);
-        if (id < 0)
-        {
-            messages::actionParameterValueFormatError(asyncResp->res, certURI,
-                                                      "CertificateUri",
-                                                      "ReplaceCertificate");
-            return;
-        }
-        std::string objectPath;
-        std::string name;
-        std::string service;
-        if (boost::starts_with(
-                certURI,
-                "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates/"))
-        {
-            objectPath =
-                std::string(certs::httpsObjectPath) + "/" + std::to_string(id);
-            name = "HTTPS certificate";
-            service = certs::httpsServiceName;
-        }
-        else if (boost::starts_with(
-                     certURI, "/redfish/v1/AccountService/LDAP/Certificates/"))
-        {
-            objectPath =
-                std::string(certs::ldapObjectPath) + "/" + std::to_string(id);
-            name = "LDAP certificate";
-            service = certs::ldapServiceName;
-        }
-        else if (boost::starts_with(
-                     certURI,
-                     "/redfish/v1/Managers/bmc/Truststore/Certificates/"))
-        {
-            objectPath = std::string(certs::authorityObjectPath) + "/" +
-                         std::to_string(id);
-            name = "TrustStore certificate";
-            service = certs::authorityServiceName;
-        }
-        else
-        {
-            messages::actionParameterNotSupported(
-                asyncResp->res, "CertificateUri", "ReplaceCertificate");
-            return;
-        }
-
-        std::shared_ptr<CertificateFile> certFile =
-            std::make_shared<CertificateFile>(certificate);
-        crow::connections::systemBus->async_method_call(
-            [asyncResp, certFile, objectPath, service, certURI, id,
-             name](const boost::system::error_code ec) {
-                if (ec)
-                {
-                    BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
-                    messages::resourceNotFound(asyncResp->res, name,
-                                               std::to_string(id));
-                    return;
-                }
-                getCertificateProperties(asyncResp, objectPath, service, id,
-                                         certURI, name);
-                BMCWEB_LOG_DEBUG << "HTTPS certificate install file="
-                                 << certFile->getCertFilePath();
-            },
-            service, objectPath, certs::certReplaceIntf, "Replace",
-            certFile->getCertFilePath());
-    }
-}; // CertificateActionsReplaceCertificate
+            std::shared_ptr<CertificateFile> certFile =
+                std::make_shared<CertificateFile>(certificate);
+            crow::connections::systemBus->async_method_call(
+                [asyncResp, certFile, objectPath, service, certURI, id,
+                 name](const boost::system::error_code ec) {
+                    if (ec)
+                    {
+                        BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
+                        messages::resourceNotFound(asyncResp->res, name,
+                                                   std::to_string(id));
+                        return;
+                    }
+                    getCertificateProperties(asyncResp, objectPath, service, id,
+                                             certURI, name);
+                    BMCWEB_LOG_DEBUG << "HTTPS certificate install file="
+                                     << certFile->getCertFilePath();
+                },
+                service, objectPath, certs::certReplaceIntf, "Replace",
+                certFile->getCertFilePath());
+        });
+} // requestRoutesCertificateActionsReplaceCertificate
 
 /**
  * Certificate resource describes a certificate used to prove the identity
  * of a component, account or service.
  */
-class HTTPSCertificate : public Node
+
+inline void requestRoutesHTTPSCertificate(App& app)
 {
-  public:
-    HTTPSCertificate(App& app) :
-        Node(app,
-             "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates/"
-             "<str>/",
-             std::string())
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
-    }
+    BMCWEB_ROUTE(
+        app,
+        "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates/<str>/")
+        .privileges({"Login"})
+        .methods(
+            boost::beast::http::verb::
+                get)([](const crow::Request& req,
+                        const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+                        const std::string& param) -> void {
+            if (param.empty())
+            {
+                messages::internalError(asyncResp->res);
+                return;
+            }
+            long id = getIDFromURL(req.url);
 
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request& req,
-               const std::vector<std::string>& params) override
-    {
-
-        if (params.size() != 1)
-        {
-            messages::internalError(asyncResp->res);
-            return;
-        }
-        long id = getIDFromURL(req.url);
-
-        BMCWEB_LOG_DEBUG << "HTTPSCertificate::doGet ID=" << std::to_string(id);
-        std::string certURL =
-            "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates/" +
-            std::to_string(id);
-        std::string objectPath = certs::httpsObjectPath;
-        objectPath += "/";
-        objectPath += std::to_string(id);
-        getCertificateProperties(asyncResp, objectPath, certs::httpsServiceName,
-                                 id, certURL, "HTTPS Certificate");
-    }
-
-}; // namespace redfish
+            BMCWEB_LOG_DEBUG << "HTTPSCertificate::doGet ID="
+                             << std::to_string(id);
+            std::string certURL =
+                "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates/" +
+                std::to_string(id);
+            std::string objectPath = certs::httpsObjectPath;
+            objectPath += "/";
+            objectPath += std::to_string(id);
+            getCertificateProperties(asyncResp, objectPath,
+                                     certs::httpsServiceName, id, certURL,
+                                     "HTTPS Certificate");
+        });
+}
 
 /**
  * Collection of HTTPS certificates
  */
-class HTTPSCertificateCollection : public Node
+inline void requestRoutesHTTPSCertificateCollection(App& app)
 {
-  public:
-    HTTPSCertificateCollection(App& app) :
-        Node(app,
-             "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates/")
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
-    }
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&, const std::vector<std::string>&) override
-    {
-        asyncResp->res.jsonValue = {
-            {"@odata.id",
-             "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates"},
-            {"@odata.type", "#CertificateCollection.CertificateCollection"},
-            {"Name", "HTTPS Certificates Collection"},
-            {"Description", "A Collection of HTTPS certificate instances"}};
+    BMCWEB_ROUTE(app,
+                 "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates/")
+        .privileges({"Login"})
+        .methods(
+            boost::beast::http::verb::
+                get)([](const crow::Request&,
+                        const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+            asyncResp->res.jsonValue = {
+                {"@odata.id",
+                 "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates"},
+                {"@odata.type", "#CertificateCollection.CertificateCollection"},
+                {"Name", "HTTPS Certificates Collection"},
+                {"Description", "A Collection of HTTPS certificate instances"}};
 
-        crow::connections::systemBus->async_method_call(
-            [asyncResp](const boost::system::error_code ec,
-                        const ManagedObjectType& certs) {
-                if (ec)
-                {
-                    BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
-                    messages::internalError(asyncResp->res);
-                    return;
-                }
-                nlohmann::json& members = asyncResp->res.jsonValue["Members"];
-                members = nlohmann::json::array();
-                for (const auto& cert : certs)
-                {
-                    long id = getIDFromURL(cert.first.str);
-                    if (id >= 0)
+            crow::connections::systemBus->async_method_call(
+                [asyncResp](const boost::system::error_code ec,
+                            const ManagedObjectType& certs) {
+                    if (ec)
                     {
-                        members.push_back(
-                            {{"@odata.id",
-                              "/redfish/v1/Managers/bmc/"
-                              "NetworkProtocol/HTTPS/Certificates/" +
-                                  std::to_string(id)}});
+                        BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
+                        messages::internalError(asyncResp->res);
+                        return;
                     }
-                }
-                asyncResp->res.jsonValue["Members@odata.count"] =
-                    members.size();
-            },
-            certs::httpsServiceName, certs::httpsObjectPath,
-            certs::dbusObjManagerIntf, "GetManagedObjects");
-    }
+                    nlohmann::json& members =
+                        asyncResp->res.jsonValue["Members"];
+                    members = nlohmann::json::array();
+                    for (const auto& cert : certs)
+                    {
+                        long id = getIDFromURL(cert.first.str);
+                        if (id >= 0)
+                        {
+                            members.push_back(
+                                {{"@odata.id",
+                                  "/redfish/v1/Managers/bmc/"
+                                  "NetworkProtocol/HTTPS/Certificates/" +
+                                      std::to_string(id)}});
+                        }
+                    }
+                    asyncResp->res.jsonValue["Members@odata.count"] =
+                        members.size();
+                },
+                certs::httpsServiceName, certs::httpsObjectPath,
+                certs::dbusObjManagerIntf, "GetManagedObjects");
+        });
 
-    void doPost(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                const crow::Request& req,
-                const std::vector<std::string>&) override
-    {
-        BMCWEB_LOG_DEBUG << "HTTPSCertificateCollection::doPost";
+    BMCWEB_ROUTE(app,
+                 "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates/")
+        .privileges({"ConfigureComponents"})
+        .methods(boost::beast::http::verb::post)(
+            [](const crow::Request& req,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                BMCWEB_LOG_DEBUG << "HTTPSCertificateCollection::doPost";
 
-        asyncResp->res.jsonValue = {{"Name", "HTTPS Certificate"},
-                                    {"Description", "HTTPS Certificate"}};
+                asyncResp->res.jsonValue = {
+                    {"Name", "HTTPS Certificate"},
+                    {"Description", "HTTPS Certificate"}};
 
-        std::string certFileBody = getCertificateFromReqBody(asyncResp, req);
+                std::string certFileBody =
+                    getCertificateFromReqBody(asyncResp, req);
 
-        if (certFileBody.empty())
-        {
-            BMCWEB_LOG_ERROR << "Cannot get certificate from request body.";
-            messages::unrecognizedRequestBody(asyncResp->res);
-            return;
-        }
-
-        std::shared_ptr<CertificateFile> certFile =
-            std::make_shared<CertificateFile>(certFileBody);
-
-        crow::connections::systemBus->async_method_call(
-            [asyncResp, certFile](const boost::system::error_code ec,
-                                  const std::string& objectPath) {
-                if (ec)
+                if (certFileBody.empty())
                 {
-                    BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
-                    messages::internalError(asyncResp->res);
+                    BMCWEB_LOG_ERROR
+                        << "Cannot get certificate from request body.";
+                    messages::unrecognizedRequestBody(asyncResp->res);
                     return;
                 }
-                long certId = getIDFromURL(objectPath);
-                if (certId < 0)
+
+                std::shared_ptr<CertificateFile> certFile =
+                    std::make_shared<CertificateFile>(certFileBody);
+
+                crow::connections::systemBus->async_method_call(
+                    [asyncResp, certFile](const boost::system::error_code ec,
+                                          const std::string& objectPath) {
+                        if (ec)
+                        {
+                            BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
+                            messages::internalError(asyncResp->res);
+                            return;
+                        }
+                        long certId = getIDFromURL(objectPath);
+                        if (certId < 0)
+                        {
+                            BMCWEB_LOG_ERROR << "Invalid objectPath value"
+                                             << objectPath;
+                            messages::internalError(asyncResp->res);
+                            return;
+                        }
+                        std::string certURL =
+                            "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/"
+                            "Certificates/" +
+                            std::to_string(certId);
+                        getCertificateProperties(
+                            asyncResp, objectPath, certs::httpsServiceName,
+                            certId, certURL, "HTTPS Certificate");
+                        BMCWEB_LOG_DEBUG << "HTTPS certificate install file="
+                                         << certFile->getCertFilePath();
+                    },
+                    certs::httpsServiceName, certs::httpsObjectPath,
+                    certs::certInstallIntf, "Install",
+                    certFile->getCertFilePath());
+            });
+} // requestRoutesHTTPSCertificateCollection
+
+/**
+ * @brief Retrieve the certificates installed list and append to the
+ * response
+ *
+ * @param[in] asyncResp Shared pointer to the response message
+ * @param[in] certURL  Path of the certificate object
+ * @param[in] path  Path of the D-Bus service object
+ * @return None
+ */
+void getCertificateLocations(
+    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+    const std::string& certURL, const std::string& path,
+    const std::string& service)
+{
+    BMCWEB_LOG_DEBUG << "getCertificateLocations URI=" << certURL
+                     << " Path=" << path << " service= " << service;
+    crow::connections::systemBus->async_method_call(
+        [asyncResp, certURL](const boost::system::error_code ec,
+                             const ManagedObjectType& certs) {
+            if (ec)
+            {
+                BMCWEB_LOG_WARNING
+                    << "Certificate collection query failed: " << ec
+                    << ", skipping " << certURL;
+                return;
+            }
+            nlohmann::json& links =
+                asyncResp->res.jsonValue["Links"]["Certificates"];
+            for (auto& cert : certs)
+            {
+                long id = getIDFromURL(cert.first.str);
+                if (id >= 0)
                 {
-                    BMCWEB_LOG_ERROR << "Invalid objectPath value"
-                                     << objectPath;
-                    messages::internalError(asyncResp->res);
-                    return;
+                    links.push_back(
+                        {{"@odata.id", certURL + std::to_string(id)}});
                 }
-                std::string certURL =
-                    "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/"
-                    "Certificates/" +
-                    std::to_string(certId);
-                getCertificateProperties(asyncResp, objectPath,
-                                         certs::httpsServiceName, certId,
-                                         certURL, "HTTPS Certificate");
-                BMCWEB_LOG_DEBUG << "HTTPS certificate install file="
-                                 << certFile->getCertFilePath();
-            },
-            certs::httpsServiceName, certs::httpsObjectPath,
-            certs::certInstallIntf, "Install", certFile->getCertFilePath());
-    }
-}; // HTTPSCertificateCollection
+            }
+            asyncResp->res.jsonValue["Links"]["Certificates@odata.count"] =
+                links.size();
+        },
+        service, path, certs::dbusObjManagerIntf, "GetManagedObjects");
+}
 
 /**
  * The certificate location schema defines a resource that an administrator
  * can use in order to locate all certificates installed on a given service.
  */
-class CertificateLocations : public Node
+inline void requestRoutesCertificateLocations(App& app)
 {
-  public:
-    CertificateLocations(App& app) :
-        Node(app, "/redfish/v1/CertificateService/CertificateLocations/")
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
-    }
+    BMCWEB_ROUTE(app, "/redfish/v1/CertificateService/CertificateLocations/")
+        .privileges({"Login"})
+        .methods(
+            boost::beast::http::verb::
+                get)([](const crow::Request&,
+                        const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+            asyncResp->res.jsonValue = {
+                {"@odata.id",
+                 "/redfish/v1/CertificateService/CertificateLocations"},
+                {"@odata.type",
+                 "#CertificateLocations.v1_0_0.CertificateLocations"},
+                {"Name", "Certificate Locations"},
+                {"Id", "CertificateLocations"},
+                {"Description",
+                 "Defines a resource that an administrator can use in order to "
+                 "locate all certificates installed on a given service"}};
 
-  private:
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&, const std::vector<std::string>&) override
-    {
-        asyncResp->res.jsonValue = {
-            {"@odata.id",
-             "/redfish/v1/CertificateService/CertificateLocations"},
-            {"@odata.type",
-             "#CertificateLocations.v1_0_0.CertificateLocations"},
-            {"Name", "Certificate Locations"},
-            {"Id", "CertificateLocations"},
-            {"Description",
-             "Defines a resource that an administrator can use in order to "
-             "locate all certificates installed on a given service"}};
-
-        nlohmann::json& links =
-            asyncResp->res.jsonValue["Links"]["Certificates"];
-        links = nlohmann::json::array();
-        getCertificateLocations(
-            asyncResp,
-            "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates/",
-            certs::httpsObjectPath, certs::httpsServiceName);
-        getCertificateLocations(asyncResp,
-                                "/redfish/v1/AccountService/LDAP/Certificates/",
-                                certs::ldapObjectPath, certs::ldapServiceName);
-        getCertificateLocations(
-            asyncResp, "/redfish/v1/Managers/bmc/Truststore/Certificates/",
-            certs::authorityObjectPath, certs::authorityServiceName);
-    }
-    /**
-     * @brief Retrieve the certificates installed list and append to the
-     * response
-     *
-     * @param[in] asyncResp Shared pointer to the response message
-     * @param[in] certURL  Path of the certificate object
-     * @param[in] path  Path of the D-Bus service object
-     * @return None
-     */
-    void getCertificateLocations(
-        const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-        const std::string& certURL, const std::string& path,
-        const std::string& service)
-    {
-        BMCWEB_LOG_DEBUG << "getCertificateLocations URI=" << certURL
-                         << " Path=" << path << " service= " << service;
-        crow::connections::systemBus->async_method_call(
-            [asyncResp, certURL](const boost::system::error_code ec,
-                                 const ManagedObjectType& certs) {
-                if (ec)
-                {
-                    BMCWEB_LOG_WARNING
-                        << "Certificate collection query failed: " << ec
-                        << ", skipping " << certURL;
-                    return;
-                }
-                nlohmann::json& links =
-                    asyncResp->res.jsonValue["Links"]["Certificates"];
-                for (auto& cert : certs)
-                {
-                    long id = getIDFromURL(cert.first.str);
-                    if (id >= 0)
-                    {
-                        links.push_back(
-                            {{"@odata.id", certURL + std::to_string(id)}});
-                    }
-                }
-                asyncResp->res.jsonValue["Links"]["Certificates@odata.count"] =
-                    links.size();
-            },
-            service, path, certs::dbusObjManagerIntf, "GetManagedObjects");
-    }
-}; // CertificateLocations
+            nlohmann::json& links =
+                asyncResp->res.jsonValue["Links"]["Certificates"];
+            links = nlohmann::json::array();
+            getCertificateLocations(
+                asyncResp,
+                "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates/",
+                certs::httpsObjectPath, certs::httpsServiceName);
+            getCertificateLocations(
+                asyncResp, "/redfish/v1/AccountService/LDAP/Certificates/",
+                certs::ldapObjectPath, certs::ldapServiceName);
+            getCertificateLocations(
+                asyncResp, "/redfish/v1/Managers/bmc/Truststore/Certificates/",
+                certs::authorityObjectPath, certs::authorityServiceName);
+        });
+}
+// requestRoutesCertificateLocations
 
 /**
  * Collection of LDAP certificates
  */
-class LDAPCertificateCollection : public Node
+inline void requestRoutesLDAPCertificateCollection(App& app)
 {
-  public:
-    LDAPCertificateCollection(App& app) :
-        Node(app, "/redfish/v1/AccountService/LDAP/Certificates/")
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
-    }
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&, const std::vector<std::string>&) override
-    {
-        asyncResp->res.jsonValue = {
-            {"@odata.id", "/redfish/v1/AccountService/LDAP/Certificates"},
-            {"@odata.type", "#CertificateCollection.CertificateCollection"},
-            {"Name", "LDAP Certificates Collection"},
-            {"Description", "A Collection of LDAP certificate instances"}};
+    BMCWEB_ROUTE(app, "/redfish/v1/AccountService/LDAP/Certificates/")
+        .privileges({"Login"})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                asyncResp->res.jsonValue = {
+                    {"@odata.id",
+                     "/redfish/v1/AccountService/LDAP/Certificates"},
+                    {"@odata.type",
+                     "#CertificateCollection.CertificateCollection"},
+                    {"Name", "LDAP Certificates Collection"},
+                    {"Description",
+                     "A Collection of LDAP certificate instances"}};
 
-        crow::connections::systemBus->async_method_call(
-            [asyncResp](const boost::system::error_code ec,
-                        const ManagedObjectType& certs) {
-                nlohmann::json& members = asyncResp->res.jsonValue["Members"];
-                nlohmann::json& count =
-                    asyncResp->res.jsonValue["Members@odata.count"];
-                members = nlohmann::json::array();
-                count = 0;
-                if (ec)
+                crow::connections::systemBus->async_method_call(
+                    [asyncResp](const boost::system::error_code ec,
+                                const ManagedObjectType& certs) {
+                        nlohmann::json& members =
+                            asyncResp->res.jsonValue["Members"];
+                        nlohmann::json& count =
+                            asyncResp->res.jsonValue["Members@odata.count"];
+                        members = nlohmann::json::array();
+                        count = 0;
+                        if (ec)
+                        {
+                            BMCWEB_LOG_WARNING
+                                << "LDAP certificate query failed: " << ec;
+                            return;
+                        }
+                        for (const auto& cert : certs)
+                        {
+                            long id = getIDFromURL(cert.first.str);
+                            if (id >= 0)
+                            {
+                                members.push_back(
+                                    {{"@odata.id", "/redfish/v1/AccountService/"
+                                                   "LDAP/Certificates/" +
+                                                       std::to_string(id)}});
+                            }
+                        }
+                        count = members.size();
+                    },
+                    certs::ldapServiceName, certs::ldapObjectPath,
+                    certs::dbusObjManagerIntf, "GetManagedObjects");
+            });
+
+    BMCWEB_ROUTE(app, "/redfish/v1/AccountService/LDAP/Certificates/")
+        .privileges({"ConfigureComponents"})
+        .methods(boost::beast::http::verb::post)(
+            [](const crow::Request& req,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                std::string certFileBody =
+                    getCertificateFromReqBody(asyncResp, req);
+
+                if (certFileBody.empty())
                 {
-                    BMCWEB_LOG_WARNING << "LDAP certificate query failed: "
-                                       << ec;
+                    BMCWEB_LOG_ERROR
+                        << "Cannot get certificate from request body.";
+                    messages::unrecognizedRequestBody(asyncResp->res);
                     return;
                 }
-                for (const auto& cert : certs)
-                {
-                    long id = getIDFromURL(cert.first.str);
-                    if (id >= 0)
-                    {
-                        members.push_back(
-                            {{"@odata.id", "/redfish/v1/AccountService/"
-                                           "LDAP/Certificates/" +
-                                               std::to_string(id)}});
-                    }
-                }
-                count = members.size();
-            },
-            certs::ldapServiceName, certs::ldapObjectPath,
-            certs::dbusObjManagerIntf, "GetManagedObjects");
-    }
 
-    void doPost(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                const crow::Request& req,
-                const std::vector<std::string>&) override
-    {
+                std::shared_ptr<CertificateFile> certFile =
+                    std::make_shared<CertificateFile>(certFileBody);
 
-        std::string certFileBody = getCertificateFromReqBody(asyncResp, req);
-
-        if (certFileBody.empty())
-        {
-            BMCWEB_LOG_ERROR << "Cannot get certificate from request body.";
-            messages::unrecognizedRequestBody(asyncResp->res);
-            return;
-        }
-
-        std::shared_ptr<CertificateFile> certFile =
-            std::make_shared<CertificateFile>(certFileBody);
-
-        crow::connections::systemBus->async_method_call(
-            [asyncResp, certFile](const boost::system::error_code ec,
-                                  const std::string& objectPath) {
-                if (ec)
-                {
-                    BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
-                    messages::internalError(asyncResp->res);
-                    return;
-                }
-                long certId = getIDFromURL(objectPath);
-                if (certId < 0)
-                {
-                    BMCWEB_LOG_ERROR << "Invalid objectPath value"
-                                     << objectPath;
-                    messages::internalError(asyncResp->res);
-                    return;
-                }
-                std::string certURL =
-                    "/redfish/v1/AccountService/LDAP/Certificates/" +
-                    std::to_string(certId);
-                getCertificateProperties(asyncResp, objectPath,
-                                         certs::ldapServiceName, certId,
-                                         certURL, "LDAP Certificate");
-                BMCWEB_LOG_DEBUG << "LDAP certificate install file="
-                                 << certFile->getCertFilePath();
-            },
-            certs::ldapServiceName, certs::ldapObjectPath,
-            certs::certInstallIntf, "Install", certFile->getCertFilePath());
-    }
-}; // LDAPCertificateCollection
+                crow::connections::systemBus->async_method_call(
+                    [asyncResp, certFile](const boost::system::error_code ec,
+                                          const std::string& objectPath) {
+                        if (ec)
+                        {
+                            BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
+                            messages::internalError(asyncResp->res);
+                            return;
+                        }
+                        long certId = getIDFromURL(objectPath);
+                        if (certId < 0)
+                        {
+                            BMCWEB_LOG_ERROR << "Invalid objectPath value"
+                                             << objectPath;
+                            messages::internalError(asyncResp->res);
+                            return;
+                        }
+                        std::string certURL =
+                            "/redfish/v1/AccountService/LDAP/Certificates/" +
+                            std::to_string(certId);
+                        getCertificateProperties(asyncResp, objectPath,
+                                                 certs::ldapServiceName, certId,
+                                                 certURL, "LDAP Certificate");
+                        BMCWEB_LOG_DEBUG << "LDAP certificate install file="
+                                         << certFile->getCertFilePath();
+                    },
+                    certs::ldapServiceName, certs::ldapObjectPath,
+                    certs::certInstallIntf, "Install",
+                    certFile->getCertFilePath());
+            });
+} // requestRoutesLDAPCertificateCollection
 
 /**
  * Certificate resource describes a certificate used to prove the identity
  * of a component, account or service.
  */
-class LDAPCertificate : public Node
+inline void requestRoutesLDAPCertificate(App& app)
 {
-  public:
-    LDAPCertificate(App& app) :
-        Node(app, "/redfish/v1/AccountService/LDAP/Certificates/<str>/",
-             std::string())
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
-    }
-
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request& req,
-               const std::vector<std::string>&) override
-    {
-
-        long id = getIDFromURL(req.url);
-        if (id < 0)
-        {
-            BMCWEB_LOG_ERROR << "Invalid url value" << req.url;
-            messages::internalError(asyncResp->res);
-            return;
-        }
-        BMCWEB_LOG_DEBUG << "LDAP Certificate ID=" << std::to_string(id);
-        std::string certURL = "/redfish/v1/AccountService/LDAP/Certificates/" +
-                              std::to_string(id);
-        std::string objectPath = certs::ldapObjectPath;
-        objectPath += "/";
-        objectPath += std::to_string(id);
-        getCertificateProperties(asyncResp, objectPath, certs::ldapServiceName,
-                                 id, certURL, "LDAP Certificate");
-    }
-}; // LDAPCertificate
+    BMCWEB_ROUTE(app, "/redfish/v1/AccountService/LDAP/Certificates/<str>/")
+        .privileges({"Login"})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request& req,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+               const std::string&) {
+                long id = getIDFromURL(req.url);
+                if (id < 0)
+                {
+                    BMCWEB_LOG_ERROR << "Invalid url value" << req.url;
+                    messages::internalError(asyncResp->res);
+                    return;
+                }
+                BMCWEB_LOG_DEBUG << "LDAP Certificate ID="
+                                 << std::to_string(id);
+                std::string certURL =
+                    "/redfish/v1/AccountService/LDAP/Certificates/" +
+                    std::to_string(id);
+                std::string objectPath = certs::ldapObjectPath;
+                objectPath += "/";
+                objectPath += std::to_string(id);
+                getCertificateProperties(asyncResp, objectPath,
+                                         certs::ldapServiceName, id, certURL,
+                                         "LDAP Certificate");
+            });
+} // requestRoutesLDAPCertificate
 /**
  * Collection of TrustStoreCertificate certificates
  */
-class TrustStoreCertificateCollection : public Node
+inline void requestRoutesTrustStoreCertificateCollection(App& app)
 {
-  public:
-    TrustStoreCertificateCollection(App& app) :
-        Node(app, "/redfish/v1/Managers/bmc/Truststore/Certificates/")
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
-    }
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&, const std::vector<std::string>&) override
-    {
-        asyncResp->res.jsonValue = {
-            {"@odata.id", "/redfish/v1/Managers/bmc/Truststore/Certificates/"},
-            {"@odata.type", "#CertificateCollection.CertificateCollection"},
-            {"Name", "TrustStore Certificates Collection"},
-            {"Description",
-             "A Collection of TrustStore certificate instances"}};
+    BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/Truststore/Certificates/")
+        .privileges({"Login"})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                asyncResp->res.jsonValue = {
+                    {"@odata.id",
+                     "/redfish/v1/Managers/bmc/Truststore/Certificates/"},
+                    {"@odata.type",
+                     "#CertificateCollection.CertificateCollection"},
+                    {"Name", "TrustStore Certificates Collection"},
+                    {"Description",
+                     "A Collection of TrustStore certificate instances"}};
 
-        crow::connections::systemBus->async_method_call(
-            [asyncResp](const boost::system::error_code ec,
-                        const ManagedObjectType& certs) {
-                if (ec)
+                crow::connections::systemBus->async_method_call(
+                    [asyncResp](const boost::system::error_code ec,
+                                const ManagedObjectType& certs) {
+                        if (ec)
+                        {
+                            BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
+                            messages::internalError(asyncResp->res);
+                            return;
+                        }
+                        nlohmann::json& members =
+                            asyncResp->res.jsonValue["Members"];
+                        members = nlohmann::json::array();
+                        for (const auto& cert : certs)
+                        {
+                            long id = getIDFromURL(cert.first.str);
+                            if (id >= 0)
+                            {
+                                members.push_back(
+                                    {{"@odata.id", "/redfish/v1/Managers/bmc/"
+                                                   "Truststore/Certificates/" +
+                                                       std::to_string(id)}});
+                            }
+                        }
+                        asyncResp->res.jsonValue["Members@odata.count"] =
+                            members.size();
+                    },
+                    certs::authorityServiceName, certs::authorityObjectPath,
+                    certs::dbusObjManagerIntf, "GetManagedObjects");
+            });
+
+    BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/Truststore/Certificates/")
+        .privileges({"ConfigureComponents"})
+        .methods(boost::beast::http::verb::post)(
+            [](const crow::Request& req,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                std::string certFileBody =
+                    getCertificateFromReqBody(asyncResp, req);
+
+                if (certFileBody.empty())
                 {
-                    BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
-                    messages::internalError(asyncResp->res);
+                    BMCWEB_LOG_ERROR
+                        << "Cannot get certificate from request body.";
+                    messages::unrecognizedRequestBody(asyncResp->res);
                     return;
                 }
-                nlohmann::json& members = asyncResp->res.jsonValue["Members"];
-                members = nlohmann::json::array();
-                for (const auto& cert : certs)
-                {
-                    long id = getIDFromURL(cert.first.str);
-                    if (id >= 0)
-                    {
-                        members.push_back(
-                            {{"@odata.id", "/redfish/v1/Managers/bmc/"
-                                           "Truststore/Certificates/" +
-                                               std::to_string(id)}});
-                    }
-                }
-                asyncResp->res.jsonValue["Members@odata.count"] =
-                    members.size();
-            },
-            certs::authorityServiceName, certs::authorityObjectPath,
-            certs::dbusObjManagerIntf, "GetManagedObjects");
-    }
 
-    void doPost(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                const crow::Request& req,
-                const std::vector<std::string>&) override
-    {
+                std::shared_ptr<CertificateFile> certFile =
+                    std::make_shared<CertificateFile>(certFileBody);
+                crow::connections::systemBus->async_method_call(
+                    [asyncResp, certFile](const boost::system::error_code ec,
+                                          const std::string& objectPath) {
+                        if (ec)
+                        {
+                            BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
+                            messages::internalError(asyncResp->res);
+                            return;
+                        }
+                        long certId = getIDFromURL(objectPath);
+                        if (certId < 0)
+                        {
+                            BMCWEB_LOG_ERROR << "Invalid objectPath value"
+                                             << objectPath;
+                            messages::internalError(asyncResp->res);
+                            return;
+                        }
+                        std::string certURL = "/redfish/v1/Managers/bmc/"
+                                              "Truststore/Certificates/" +
+                                              std::to_string(certId);
 
-        std::string certFileBody = getCertificateFromReqBody(asyncResp, req);
-
-        if (certFileBody.empty())
-        {
-            BMCWEB_LOG_ERROR << "Cannot get certificate from request body.";
-            messages::unrecognizedRequestBody(asyncResp->res);
-            return;
-        }
-
-        std::shared_ptr<CertificateFile> certFile =
-            std::make_shared<CertificateFile>(certFileBody);
-        crow::connections::systemBus->async_method_call(
-            [asyncResp, certFile](const boost::system::error_code ec,
-                                  const std::string& objectPath) {
-                if (ec)
-                {
-                    BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
-                    messages::internalError(asyncResp->res);
-                    return;
-                }
-                long certId = getIDFromURL(objectPath);
-                if (certId < 0)
-                {
-                    BMCWEB_LOG_ERROR << "Invalid objectPath value"
-                                     << objectPath;
-                    messages::internalError(asyncResp->res);
-                    return;
-                }
-                std::string certURL = "/redfish/v1/Managers/bmc/"
-                                      "Truststore/Certificates/" +
-                                      std::to_string(certId);
-
-                getCertificateProperties(asyncResp, objectPath,
-                                         certs::authorityServiceName, certId,
-                                         certURL, "TrustStore Certificate");
-                BMCWEB_LOG_DEBUG << "TrustStore certificate install file="
-                                 << certFile->getCertFilePath();
-            },
-            certs::authorityServiceName, certs::authorityObjectPath,
-            certs::certInstallIntf, "Install", certFile->getCertFilePath());
-    }
-}; // TrustStoreCertificateCollection
+                        getCertificateProperties(
+                            asyncResp, objectPath, certs::authorityServiceName,
+                            certId, certURL, "TrustStore Certificate");
+                        BMCWEB_LOG_DEBUG
+                            << "TrustStore certificate install file="
+                            << certFile->getCertFilePath();
+                    },
+                    certs::authorityServiceName, certs::authorityObjectPath,
+                    certs::certInstallIntf, "Install",
+                    certFile->getCertFilePath());
+            });
+} // requestRoutesTrustStoreCertificateCollection
 
 /**
  * Certificate resource describes a certificate used to prove the identity
  * of a component, account or service.
  */
-class TrustStoreCertificate : public Node
+inline void requestRoutesTrustStoreCertificate(App& app)
 {
-  public:
-    TrustStoreCertificate(App& app) :
-        Node(app, "/redfish/v1/Managers/bmc/Truststore/Certificates/<str>/",
-             std::string())
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
-    }
-
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request& req,
-               const std::vector<std::string>&) override
-    {
-
-        long id = getIDFromURL(req.url);
-        if (id < 0)
-        {
-            BMCWEB_LOG_ERROR << "Invalid url value" << req.url;
-            messages::internalError(asyncResp->res);
-            return;
-        }
-        BMCWEB_LOG_DEBUG << "TrustStoreCertificate::doGet ID="
-                         << std::to_string(id);
-        std::string certURL =
-            "/redfish/v1/Managers/bmc/Truststore/Certificates/" +
-            std::to_string(id);
-        std::string objectPath = certs::authorityObjectPath;
-        objectPath += "/";
-        objectPath += std::to_string(id);
-        getCertificateProperties(asyncResp, objectPath,
-                                 certs::authorityServiceName, id, certURL,
-                                 "TrustStore Certificate");
-    }
-
-    void doDelete(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                  const crow::Request& req,
-                  const std::vector<std::string>& params) override
-    {
-
-        if (params.size() != 1)
-        {
-            messages::internalError(asyncResp->res);
-            return;
-        }
-
-        long id = getIDFromURL(req.url);
-        if (id < 0)
-        {
-            BMCWEB_LOG_ERROR << "Invalid url value: " << req.url;
-            messages::resourceNotFound(asyncResp->res, "TrustStore Certificate",
-                                       std::string(req.url));
-            return;
-        }
-        BMCWEB_LOG_DEBUG << "TrustStoreCertificate::doDelete ID="
-                         << std::to_string(id);
-        std::string certPath = certs::authorityObjectPath;
-        certPath += "/";
-        certPath += std::to_string(id);
-
-        crow::connections::systemBus->async_method_call(
-            [asyncResp, id](const boost::system::error_code ec) {
-                if (ec)
+    BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/Truststore/Certificates/<str>/")
+        .privileges({"Loign"})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request& req,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+               const std::string&) {
+                long id = getIDFromURL(req.url);
+                if (id < 0)
                 {
-                    messages::resourceNotFound(asyncResp->res,
-                                               "TrustStore Certificate",
-                                               std::to_string(id));
+                    BMCWEB_LOG_ERROR << "Invalid url value" << req.url;
+                    messages::internalError(asyncResp->res);
                     return;
                 }
-                BMCWEB_LOG_INFO << "Certificate deleted";
-                asyncResp->res.result(boost::beast::http::status::no_content);
-            },
-            certs::authorityServiceName, certPath, certs::objDeleteIntf,
-            "Delete");
-    }
-}; // TrustStoreCertificate
+                BMCWEB_LOG_DEBUG << "TrustStoreCertificate::doGet ID="
+                                 << std::to_string(id);
+                std::string certURL =
+                    "/redfish/v1/Managers/bmc/Truststore/Certificates/" +
+                    std::to_string(id);
+                std::string objectPath = certs::authorityObjectPath;
+                objectPath += "/";
+                objectPath += std::to_string(id);
+                getCertificateProperties(asyncResp, objectPath,
+                                         certs::authorityServiceName, id,
+                                         certURL, "TrustStore Certificate");
+            });
+
+    BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/Truststore/Certificates/<str>/")
+        .privileges({"ConfigureComponents"})
+        .methods(boost::beast::http::verb::delete_)(
+            [](const crow::Request& req,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+               const std::string& param) {
+                if (param.empty())
+                {
+                    messages::internalError(asyncResp->res);
+                    return;
+                }
+
+                long id = getIDFromURL(req.url);
+                if (id < 0)
+                {
+                    BMCWEB_LOG_ERROR << "Invalid url value: " << req.url;
+                    messages::resourceNotFound(asyncResp->res,
+                                               "TrustStore Certificate",
+                                               std::string(req.url));
+                    return;
+                }
+                BMCWEB_LOG_DEBUG << "TrustStoreCertificate::doDelete ID="
+                                 << std::to_string(id);
+                std::string certPath = certs::authorityObjectPath;
+                certPath += "/";
+                certPath += std::to_string(id);
+
+                crow::connections::systemBus->async_method_call(
+                    [asyncResp, id](const boost::system::error_code ec) {
+                        if (ec)
+                        {
+                            messages::resourceNotFound(asyncResp->res,
+                                                       "TrustStore Certificate",
+                                                       std::to_string(id));
+                            return;
+                        }
+                        BMCWEB_LOG_INFO << "Certificate deleted";
+                        asyncResp->res.result(
+                            boost::beast::http::status::no_content);
+                    },
+                    certs::authorityServiceName, certPath, certs::objDeleteIntf,
+                    "Delete");
+            });
+} // requestRoutesTrustStoreCertificate
 } // namespace redfish
diff --git a/redfish-core/lib/chassis.hpp b/redfish-core/lib/chassis.hpp
index e96a678..22fa0cc 100644
--- a/redfish-core/lib/chassis.hpp
+++ b/redfish-core/lib/chassis.hpp
@@ -17,8 +17,8 @@
 
 #include "health.hpp"
 #include "led.hpp"
-#include "node.hpp"
 
+#include <app.hpp>
 #include <boost/container/flat_map.hpp>
 #include <utils/collection.hpp>
 
@@ -157,398 +157,382 @@
 
 /**
  * ChassisCollection derived class for delivering Chassis Collection Schema
+ *  Functions triggers appropriate requests on DBus
  */
-class ChassisCollection : public Node
+inline void requestRoutesChassisCollection(App& app)
 {
-  public:
-    ChassisCollection(App& app) : Node(app, "/redfish/v1/Chassis/")
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
-    }
+    BMCWEB_ROUTE(app, "/redfish/v1/Chassis/")
+        .privileges({"Login"})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                asyncResp->res.jsonValue["@odata.type"] =
+                    "#ChassisCollection.ChassisCollection";
+                asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Chassis";
+                asyncResp->res.jsonValue["Name"] = "Chassis Collection";
 
-  private:
-    /**
-     * Functions triggers appropriate requests on DBus
-     */
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&, const std::vector<std::string>&) override
-    {
-        asyncResp->res.jsonValue["@odata.type"] =
-            "#ChassisCollection.ChassisCollection";
-        asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Chassis";
-        asyncResp->res.jsonValue["Name"] = "Chassis Collection";
-
-        collection_util::getCollectionMembers(
-            asyncResp, "/redfish/v1/Chassis",
-            {"xyz.openbmc_project.Inventory.Item.Board",
-             "xyz.openbmc_project.Inventory.Item.Chassis"});
-    }
-};
+                collection_util::getCollectionMembers(
+                    asyncResp, "/redfish/v1/Chassis",
+                    {"xyz.openbmc_project.Inventory.Item.Board",
+                     "xyz.openbmc_project.Inventory.Item.Chassis"});
+            });
+}
 
 /**
  * Chassis override class for delivering Chassis Schema
+ * Functions triggers appropriate requests on DBus
  */
-class Chassis : public Node
+inline void requestRoutesChassis(App& app)
 {
-  public:
-    Chassis(App& app) : Node(app, "/redfish/v1/Chassis/<str>/", std::string())
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
-    }
+    BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/")
+        .privileges({"Login"})
+        .methods(
+            boost::beast::http::verb::get)([](const crow::Request&,
+                                              const std::shared_ptr<
+                                                  bmcweb::AsyncResp>& asyncResp,
+                                              const std::string& chassisId) {
+            const std::array<const char*, 2> interfaces = {
+                "xyz.openbmc_project.Inventory.Item.Board",
+                "xyz.openbmc_project.Inventory.Item.Chassis"};
 
-  private:
-    /**
-     * Functions triggers appropriate requests on DBus
-     */
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&,
-               const std::vector<std::string>& params) override
-    {
-        const std::array<const char*, 2> interfaces = {
-            "xyz.openbmc_project.Inventory.Item.Board",
-            "xyz.openbmc_project.Inventory.Item.Chassis"};
-
-        // Check if there is required param, truly entering this shall be
-        // impossible.
-        if (params.size() != 1)
-        {
-            messages::internalError(asyncResp->res);
-            return;
-        }
-        const std::string& chassisId = params[0];
-
-        crow::connections::systemBus->async_method_call(
-            [asyncResp, chassisId(std::string(chassisId))](
-                const boost::system::error_code ec,
-                const crow::openbmc_mapper::GetSubTreeType& subtree) {
-                if (ec)
-                {
-                    messages::internalError(asyncResp->res);
-                    return;
-                }
-                // Iterate over all retrieved ObjectPaths.
-                for (const std::pair<
-                         std::string,
-                         std::vector<
-                             std::pair<std::string, std::vector<std::string>>>>&
-                         object : subtree)
-                {
-                    const std::string& path = object.first;
-                    const std::vector<
-                        std::pair<std::string, std::vector<std::string>>>&
-                        connectionNames = object.second;
-                    sdbusplus::message::object_path objPath(path);
-                    if (objPath.filename() != chassisId)
+            crow::connections::systemBus->async_method_call(
+                [asyncResp, chassisId(std::string(chassisId))](
+                    const boost::system::error_code ec,
+                    const crow::openbmc_mapper::GetSubTreeType& subtree) {
+                    if (ec)
                     {
-                        continue;
+                        messages::internalError(asyncResp->res);
+                        return;
                     }
-
-                    auto health = std::make_shared<HealthPopulate>(asyncResp);
-
-                    crow::connections::systemBus->async_method_call(
-                        [health](const boost::system::error_code ec2,
-                                 std::variant<std::vector<std::string>>& resp) {
-                            if (ec2)
-                            {
-                                return; // no sensors = no failures
-                            }
-                            std::vector<std::string>* data =
-                                std::get_if<std::vector<std::string>>(&resp);
-                            if (data == nullptr)
-                            {
-                                return;
-                            }
-                            health->inventory = std::move(*data);
-                        },
-                        "xyz.openbmc_project.ObjectMapper",
-                        path + "/all_sensors",
-                        "org.freedesktop.DBus.Properties", "Get",
-                        "xyz.openbmc_project.Association", "endpoints");
-
-                    health->populate();
-
-                    if (connectionNames.size() < 1)
+                    // Iterate over all retrieved ObjectPaths.
+                    for (const std::pair<
+                             std::string,
+                             std::vector<std::pair<std::string,
+                                                   std::vector<std::string>>>>&
+                             object : subtree)
                     {
-                        BMCWEB_LOG_ERROR << "Got 0 Connection names";
-                        continue;
-                    }
+                        const std::string& path = object.first;
+                        const std::vector<
+                            std::pair<std::string, std::vector<std::string>>>&
+                            connectionNames = object.second;
 
-                    asyncResp->res.jsonValue["@odata.type"] =
-                        "#Chassis.v1_14_0.Chassis";
-                    asyncResp->res.jsonValue["@odata.id"] =
-                        "/redfish/v1/Chassis/" + chassisId;
-                    asyncResp->res.jsonValue["Name"] = "Chassis Collection";
-                    asyncResp->res.jsonValue["ChassisType"] = "RackMount";
-                    asyncResp->res.jsonValue["Actions"]["#Chassis.Reset"] = {
-                        {"target", "/redfish/v1/Chassis/" + chassisId +
-                                       "/Actions/Chassis.Reset"},
-                        {"@Redfish.ActionInfo", "/redfish/v1/Chassis/" +
-                                                    chassisId +
-                                                    "/ResetActionInfo"}};
-                    asyncResp->res.jsonValue["PCIeDevices"] = {
-                        {"@odata.id",
-                         "/redfish/v1/Systems/system/PCIeDevices"}};
-
-                    const std::string& connectionName =
-                        connectionNames[0].first;
-
-                    const std::vector<std::string>& interfaces2 =
-                        connectionNames[0].second;
-                    const std::array<const char*, 2> hasIndicatorLed = {
-                        "xyz.openbmc_project.Inventory.Item.Panel",
-                        "xyz.openbmc_project.Inventory.Item.Board.Motherboard"};
-
-                    for (const char* interface : hasIndicatorLed)
-                    {
-                        if (std::find(interfaces2.begin(), interfaces2.end(),
-                                      interface) != interfaces2.end())
+                        if (!boost::ends_with(path, chassisId))
                         {
-                            getIndicatorLedState(asyncResp);
-                            getLocationIndicatorActive(asyncResp);
-                            break;
+                            continue;
                         }
-                    }
 
-                    const std::string locationInterface =
-                        "xyz.openbmc_project.Inventory.Decorator.LocationCode";
-                    if (std::find(interfaces2.begin(), interfaces2.end(),
-                                  locationInterface) != interfaces2.end())
-                    {
+                        auto health =
+                            std::make_shared<HealthPopulate>(asyncResp);
+
+                        crow::connections::systemBus->async_method_call(
+                            [health](
+                                const boost::system::error_code ec2,
+                                std::variant<std::vector<std::string>>& resp) {
+                                if (ec2)
+                                {
+                                    return; // no sensors = no failures
+                                }
+                                std::vector<std::string>* data =
+                                    std::get_if<std::vector<std::string>>(
+                                        &resp);
+                                if (data == nullptr)
+                                {
+                                    return;
+                                }
+                                health->inventory = std::move(*data);
+                            },
+                            "xyz.openbmc_project.ObjectMapper",
+                            path + "/all_sensors",
+                            "org.freedesktop.DBus.Properties", "Get",
+                            "xyz.openbmc_project.Association", "endpoints");
+
+                        health->populate();
+
+                        if (connectionNames.size() < 1)
+                        {
+                            BMCWEB_LOG_ERROR << "Got 0 Connection names";
+                            continue;
+                        }
+
+                        asyncResp->res.jsonValue["@odata.type"] =
+                            "#Chassis.v1_14_0.Chassis";
+                        asyncResp->res.jsonValue["@odata.id"] =
+                            "/redfish/v1/Chassis/" + chassisId;
+                        asyncResp->res.jsonValue["Name"] = "Chassis Collection";
+                        asyncResp->res.jsonValue["ChassisType"] = "RackMount";
+                        asyncResp->res.jsonValue["Actions"]["#Chassis.Reset"] =
+                            {{"target", "/redfish/v1/Chassis/" + chassisId +
+                                            "/Actions/Chassis.Reset"},
+                             {"@Redfish.ActionInfo", "/redfish/v1/Chassis/" +
+                                                         chassisId +
+                                                         "/ResetActionInfo"}};
+                        asyncResp->res.jsonValue["PCIeDevices"] = {
+                            {"@odata.id",
+                             "/redfish/v1/Systems/system/PCIeDevices"}};
+
+                        const std::string& connectionName =
+                            connectionNames[0].first;
+
+                        const std::vector<std::string>& interfaces2 =
+                            connectionNames[0].second;
+                        const std::array<const char*, 2> hasIndicatorLed = {
+                            "xyz.openbmc_project.Inventory.Item.Panel",
+                            "xyz.openbmc_project.Inventory.Item.Board."
+                            "Motherboard"};
+
+                        for (const char* interface : hasIndicatorLed)
+                        {
+                            if (std::find(interfaces2.begin(),
+                                          interfaces2.end(),
+                                          interface) != interfaces2.end())
+                            {
+                                getIndicatorLedState(asyncResp);
+                                getLocationIndicatorActive(asyncResp);
+                                break;
+                            }
+                        }
+
+                        const std::string locationInterface =
+                            "xyz.openbmc_project.Inventory.Decorator."
+                            "LocationCode";
+                        if (std::find(interfaces2.begin(), interfaces2.end(),
+                                      locationInterface) != interfaces2.end())
+                        {
+                            crow::connections::systemBus->async_method_call(
+                                [asyncResp, chassisId(std::string(chassisId))](
+                                    const boost::system::error_code ec,
+                                    const std::variant<std::string>& property) {
+                                    if (ec)
+                                    {
+                                        BMCWEB_LOG_DEBUG
+                                            << "DBUS response error for "
+                                               "Location";
+                                        messages::internalError(asyncResp->res);
+                                        return;
+                                    }
+
+                                    const std::string* value =
+                                        std::get_if<std::string>(&property);
+                                    if (value == nullptr)
+                                    {
+                                        BMCWEB_LOG_DEBUG
+                                            << "Null value returned "
+                                               "for locaton code";
+                                        messages::internalError(asyncResp->res);
+                                        return;
+                                    }
+                                    asyncResp->res
+                                        .jsonValue["Location"]["PartLocation"]
+                                                  ["ServiceLabel"] = *value;
+                                },
+                                connectionName, path,
+                                "org.freedesktop.DBus.Properties", "Get",
+                                locationInterface, "LocationCode");
+                        }
+
                         crow::connections::systemBus->async_method_call(
                             [asyncResp, chassisId(std::string(chassisId))](
-                                const boost::system::error_code ec,
-                                const std::variant<std::string>& property) {
-                                if (ec)
+                                const boost::system::error_code /*ec2*/,
+                                const std::vector<
+                                    std::pair<std::string, VariantType>>&
+                                    propertiesList) {
+                                for (const std::pair<std::string, VariantType>&
+                                         property : propertiesList)
                                 {
-                                    BMCWEB_LOG_DEBUG
-                                        << "DBUS response error for Location";
-                                    messages::internalError(asyncResp->res);
-                                    return;
-                                }
-
-                                const std::string* value =
-                                    std::get_if<std::string>(&property);
-                                if (value == nullptr)
-                                {
-                                    BMCWEB_LOG_DEBUG << "Null value returned "
-                                                        "for locaton code";
-                                    messages::internalError(asyncResp->res);
-                                    return;
-                                }
-                                asyncResp->res
-                                    .jsonValue["Location"]["PartLocation"]
-                                              ["ServiceLabel"] = *value;
-                            },
-                            connectionName, path,
-                            "org.freedesktop.DBus.Properties", "Get",
-                            locationInterface, "LocationCode");
-                    }
-
-                    crow::connections::systemBus->async_method_call(
-                        [asyncResp, chassisId(std::string(chassisId))](
-                            const boost::system::error_code /*ec2*/,
-                            const std::vector<std::pair<
-                                std::string, VariantType>>& propertiesList) {
-                            for (const std::pair<std::string, VariantType>&
-                                     property : propertiesList)
-                            {
-                                // Store DBus properties that are also Redfish
-                                // properties with same name and a string value
-                                const std::string& propertyName =
-                                    property.first;
-                                if ((propertyName == "PartNumber") ||
-                                    (propertyName == "SerialNumber") ||
-                                    (propertyName == "Manufacturer") ||
-                                    (propertyName == "Model"))
-                                {
-                                    const std::string* value =
-                                        std::get_if<std::string>(
-                                            &property.second);
-                                    if (value != nullptr)
+                                    // Store DBus properties that are also
+                                    // Redfish properties with same name and a
+                                    // string value
+                                    const std::string& propertyName =
+                                        property.first;
+                                    if ((propertyName == "PartNumber") ||
+                                        (propertyName == "SerialNumber") ||
+                                        (propertyName == "Manufacturer") ||
+                                        (propertyName == "Model"))
                                     {
-                                        asyncResp->res.jsonValue[propertyName] =
-                                            *value;
+                                        const std::string* value =
+                                            std::get_if<std::string>(
+                                                &property.second);
+                                        if (value != nullptr)
+                                        {
+                                            asyncResp->res
+                                                .jsonValue[propertyName] =
+                                                *value;
+                                        }
                                     }
                                 }
+                                asyncResp->res.jsonValue["Name"] = chassisId;
+                                asyncResp->res.jsonValue["Id"] = chassisId;
+                                asyncResp->res.jsonValue["Thermal"] = {
+                                    {"@odata.id", "/redfish/v1/Chassis/" +
+                                                      chassisId + "/Thermal"}};
+                                // Power object
+                                asyncResp->res.jsonValue["Power"] = {
+                                    {"@odata.id", "/redfish/v1/Chassis/" +
+                                                      chassisId + "/Power"}};
+                                // SensorCollection
+                                asyncResp->res.jsonValue["Sensors"] = {
+                                    {"@odata.id", "/redfish/v1/Chassis/" +
+                                                      chassisId + "/Sensors"}};
+                                asyncResp->res.jsonValue["Status"] = {
+                                    {"State", "Enabled"},
+                                };
+
+                                asyncResp->res
+                                    .jsonValue["Links"]["ComputerSystems"] = {
+                                    {{"@odata.id",
+                                      "/redfish/v1/Systems/system"}}};
+                                asyncResp->res.jsonValue["Links"]["ManagedBy"] =
+                                    {{{"@odata.id",
+                                       "/redfish/v1/Managers/bmc"}}};
+                                getChassisState(asyncResp);
+                            },
+                            connectionName, path,
+                            "org.freedesktop.DBus.Properties", "GetAll",
+                            "xyz.openbmc_project.Inventory.Decorator.Asset");
+                        return;
+                    }
+
+                    // Couldn't find an object with that name.  return an error
+                    messages::resourceNotFound(
+                        asyncResp->res, "#Chassis.v1_14_0.Chassis", chassisId);
+                },
+                "xyz.openbmc_project.ObjectMapper",
+                "/xyz/openbmc_project/object_mapper",
+                "xyz.openbmc_project.ObjectMapper", "GetSubTree",
+                "/xyz/openbmc_project/inventory", 0, interfaces);
+
+            getPhysicalSecurityData(asyncResp);
+        });
+
+    BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/")
+        .privileges({"ConfigureComponents"})
+        .methods(
+            boost::beast::http::verb::
+                patch)([](const crow::Request& req,
+                          const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+                          const std::string& param) {
+            std::optional<bool> locationIndicatorActive;
+            std::optional<std::string> indicatorLed;
+
+            if (param.empty())
+            {
+                return;
+            }
+
+            if (!json_util::readJson(
+                    req, asyncResp->res, "LocationIndicatorActive",
+                    locationIndicatorActive, "IndicatorLED", indicatorLed))
+            {
+                return;
+            }
+
+            // TODO (Gunnar): Remove IndicatorLED after enough time has passed
+            if (!locationIndicatorActive && !indicatorLed)
+            {
+                return; // delete this when we support more patch properties
+            }
+            if (indicatorLed)
+            {
+                asyncResp->res.addHeader(
+                    boost::beast::http::field::warning,
+                    "299 - \"IndicatorLED is deprecated. Use "
+                    "LocationIndicatorActive instead.\"");
+            }
+
+            const std::array<const char*, 2> interfaces = {
+                "xyz.openbmc_project.Inventory.Item.Board",
+                "xyz.openbmc_project.Inventory.Item.Chassis"};
+
+            const std::string& chassisId = param;
+
+            crow::connections::systemBus->async_method_call(
+                [asyncResp, chassisId, locationIndicatorActive, indicatorLed](
+                    const boost::system::error_code ec,
+                    const crow::openbmc_mapper::GetSubTreeType& subtree) {
+                    if (ec)
+                    {
+                        messages::internalError(asyncResp->res);
+                        return;
+                    }
+
+                    // Iterate over all retrieved ObjectPaths.
+                    for (const std::pair<
+                             std::string,
+                             std::vector<std::pair<std::string,
+                                                   std::vector<std::string>>>>&
+                             object : subtree)
+                    {
+                        const std::string& path = object.first;
+                        const std::vector<
+                            std::pair<std::string, std::vector<std::string>>>&
+                            connectionNames = object.second;
+
+                        if (!boost::ends_with(path, chassisId))
+                        {
+                            continue;
+                        }
+
+                        if (connectionNames.size() < 1)
+                        {
+                            BMCWEB_LOG_ERROR << "Got 0 Connection names";
+                            continue;
+                        }
+
+                        const std::vector<std::string>& interfaces3 =
+                            connectionNames[0].second;
+
+                        const std::array<const char*, 2> hasIndicatorLed = {
+                            "xyz.openbmc_project.Inventory.Item.Panel",
+                            "xyz.openbmc_project.Inventory.Item.Board."
+                            "Motherboard"};
+                        bool indicatorChassis = false;
+                        for (const char* interface : hasIndicatorLed)
+                        {
+                            if (std::find(interfaces3.begin(),
+                                          interfaces3.end(),
+                                          interface) != interfaces3.end())
+                            {
+                                indicatorChassis = true;
+                                break;
                             }
-                            asyncResp->res.jsonValue["Name"] = chassisId;
-                            asyncResp->res.jsonValue["Id"] = chassisId;
-                            asyncResp->res.jsonValue["Thermal"] = {
-                                {"@odata.id", "/redfish/v1/Chassis/" +
-                                                  chassisId + "/Thermal"}};
-                            // Power object
-                            asyncResp->res.jsonValue["Power"] = {
-                                {"@odata.id", "/redfish/v1/Chassis/" +
-                                                  chassisId + "/Power"}};
-                            // SensorCollection
-                            asyncResp->res.jsonValue["Sensors"] = {
-                                {"@odata.id", "/redfish/v1/Chassis/" +
-                                                  chassisId + "/Sensors"}};
-                            asyncResp->res.jsonValue["Status"] = {
-                                {"State", "Enabled"},
-                            };
-
-                            asyncResp->res
-                                .jsonValue["Links"]["ComputerSystems"] = {
-                                {{"@odata.id", "/redfish/v1/Systems/system"}}};
-                            asyncResp->res.jsonValue["Links"]["ManagedBy"] = {
-                                {{"@odata.id", "/redfish/v1/Managers/bmc"}}};
-                            getChassisState(asyncResp);
-                        },
-                        connectionName, path, "org.freedesktop.DBus.Properties",
-                        "GetAll",
-                        "xyz.openbmc_project.Inventory.Decorator.Asset");
-                    return;
-                }
-
-                // Couldn't find an object with that name.  return an error
-                messages::resourceNotFound(
-                    asyncResp->res, "#Chassis.v1_14_0.Chassis", chassisId);
-            },
-            "xyz.openbmc_project.ObjectMapper",
-            "/xyz/openbmc_project/object_mapper",
-            "xyz.openbmc_project.ObjectMapper", "GetSubTree",
-            "/xyz/openbmc_project/inventory", 0, interfaces);
-
-        getPhysicalSecurityData(asyncResp);
-    }
-
-    void doPatch(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                 const crow::Request& req,
-                 const std::vector<std::string>& params) override
-    {
-        std::optional<bool> locationIndicatorActive;
-        std::optional<std::string> indicatorLed;
-
-        if (params.size() != 1)
-        {
-            return;
-        }
-
-        if (!json_util::readJson(req, asyncResp->res, "LocationIndicatorActive",
-                                 locationIndicatorActive, "IndicatorLED",
-                                 indicatorLed))
-        {
-            return;
-        }
-
-        // TODO (Gunnar): Remove IndicatorLED after enough time has passed
-        if (!locationIndicatorActive && !indicatorLed)
-        {
-            return; // delete this when we support more patch properties
-        }
-        if (indicatorLed)
-        {
-            asyncResp->res.addHeader(boost::beast::http::field::warning,
-                                     "299 - \"IndicatorLED is deprecated. Use "
-                                     "LocationIndicatorActive instead.\"");
-        }
-
-        const std::array<const char*, 2> interfaces = {
-            "xyz.openbmc_project.Inventory.Item.Board",
-            "xyz.openbmc_project.Inventory.Item.Chassis"};
-
-        const std::string& chassisId = params[0];
-
-        crow::connections::systemBus->async_method_call(
-            [asyncResp, chassisId, locationIndicatorActive, indicatorLed](
-                const boost::system::error_code ec,
-                const crow::openbmc_mapper::GetSubTreeType& subtree) {
-                if (ec)
-                {
-                    messages::internalError(asyncResp->res);
-                    return;
-                }
-
-                // Iterate over all retrieved ObjectPaths.
-                for (const std::pair<
-                         std::string,
-                         std::vector<
-                             std::pair<std::string, std::vector<std::string>>>>&
-                         object : subtree)
-                {
-                    const std::string& path = object.first;
-                    const std::vector<
-                        std::pair<std::string, std::vector<std::string>>>&
-                        connectionNames = object.second;
-
-                    if (!boost::ends_with(path, chassisId))
-                    {
-                        continue;
+                        }
+                        if (locationIndicatorActive)
+                        {
+                            if (indicatorChassis)
+                            {
+                                setLocationIndicatorActive(
+                                    asyncResp, *locationIndicatorActive);
+                            }
+                            else
+                            {
+                                messages::propertyUnknown(
+                                    asyncResp->res, "LocationIndicatorActive");
+                            }
+                        }
+                        if (indicatorLed)
+                        {
+                            if (indicatorChassis)
+                            {
+                                setIndicatorLedState(asyncResp, *indicatorLed);
+                            }
+                            else
+                            {
+                                messages::propertyUnknown(asyncResp->res,
+                                                          "IndicatorLED");
+                            }
+                        }
+                        return;
                     }
 
-                    if (connectionNames.size() < 1)
-                    {
-                        BMCWEB_LOG_ERROR << "Got 0 Connection names";
-                        continue;
-                    }
-
-                    const std::vector<std::string>& interfaces3 =
-                        connectionNames[0].second;
-
-                    const std::array<const char*, 2> hasIndicatorLed = {
-                        "xyz.openbmc_project.Inventory.Item.Panel",
-                        "xyz.openbmc_project.Inventory.Item.Board."
-                        "Motherboard"};
-                    bool indicatorChassis = false;
-                    for (const char* interface : hasIndicatorLed)
-                    {
-                        if (std::find(interfaces3.begin(), interfaces3.end(),
-                                      interface) != interfaces3.end())
-                        {
-                            indicatorChassis = true;
-                            break;
-                        }
-                    }
-                    if (locationIndicatorActive)
-                    {
-                        if (indicatorChassis)
-                        {
-                            setLocationIndicatorActive(
-                                asyncResp, *locationIndicatorActive);
-                        }
-                        else
-                        {
-                            messages::propertyUnknown(
-                                asyncResp->res, "LocationIndicatorActive");
-                        }
-                    }
-                    if (indicatorLed)
-                    {
-                        if (indicatorChassis)
-                        {
-                            setIndicatorLedState(asyncResp, *indicatorLed);
-                        }
-                        else
-                        {
-                            messages::propertyUnknown(asyncResp->res,
-                                                      "IndicatorLED");
-                        }
-                    }
-                    return;
-                }
-
-                messages::resourceNotFound(
-                    asyncResp->res, "#Chassis.v1_14_0.Chassis", chassisId);
-            },
-            "xyz.openbmc_project.ObjectMapper",
-            "/xyz/openbmc_project/object_mapper",
-            "xyz.openbmc_project.ObjectMapper", "GetSubTree",
-            "/xyz/openbmc_project/inventory", 0, interfaces);
-    }
-};
+                    messages::resourceNotFound(
+                        asyncResp->res, "#Chassis.v1_14_0.Chassis", chassisId);
+                },
+                "xyz.openbmc_project.ObjectMapper",
+                "/xyz/openbmc_project/object_mapper",
+                "xyz.openbmc_project.ObjectMapper", "GetSubTree",
+                "/xyz/openbmc_project/inventory", 0, interfaces);
+        });
+}
 
 inline void
     doChassisPowerCycle(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
@@ -613,98 +597,67 @@
 /**
  * ChassisResetAction class supports the POST method for the Reset
  * action.
+ * Function handles POST method request.
+ * Analyzes POST body before sending Reset request data to D-Bus.
  */
-class ChassisResetAction : public Node
+
+inline void requestRoutesChassisResetAction(App& app)
 {
-  public:
-    ChassisResetAction(App& app) :
-        Node(app, "/redfish/v1/Chassis/<str>/Actions/Chassis.Reset/",
-             std::string())
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
-    }
+    BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/Actions/Chassis.Reset/")
+        .privileges({"ConfigureComponents"})
+        .methods(boost::beast::http::verb::post)(
+            [](const crow::Request& req,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+               const std::string&) {
+                BMCWEB_LOG_DEBUG << "Post Chassis Reset.";
 
-  private:
-    /**
-     * Function handles POST method request.
-     * Analyzes POST body before sending Reset request data to D-Bus.
-     */
-    void doPost(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                const crow::Request& req,
-                const std::vector<std::string>&) override
-    {
-        BMCWEB_LOG_DEBUG << "Post Chassis Reset.";
+                std::string resetType;
 
-        std::string resetType;
+                if (!json_util::readJson(req, asyncResp->res, "ResetType",
+                                         resetType))
+                {
+                    return;
+                }
 
-        if (!json_util::readJson(req, asyncResp->res, "ResetType", resetType))
-        {
-            return;
-        }
+                if (resetType != "PowerCycle")
+                {
+                    BMCWEB_LOG_DEBUG << "Invalid property value for ResetType: "
+                                     << resetType;
+                    messages::actionParameterNotSupported(
+                        asyncResp->res, resetType, "ResetType");
 
-        if (resetType != "PowerCycle")
-        {
-            BMCWEB_LOG_DEBUG << "Invalid property value for ResetType: "
-                             << resetType;
-            messages::actionParameterNotSupported(asyncResp->res, resetType,
-                                                  "ResetType");
-
-            return;
-        }
-        doChassisPowerCycle(asyncResp);
-    }
-};
+                    return;
+                }
+                doChassisPowerCycle(asyncResp);
+            });
+}
 
 /**
  * ChassisResetActionInfo derived class for delivering Chassis
  * ResetType AllowableValues using ResetInfo schema.
  */
-class ChassisResetActionInfo : public Node
+inline void requestRoutesChassisResetActionInfo(App& app)
 {
-  public:
-    /*
-     * Default Constructor
-     */
-    ChassisResetActionInfo(App& app) :
-        Node(app, "/redfish/v1/Chassis/<str>/ResetActionInfo/", std::string())
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
-    }
+    BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/ResetActionInfo/")
+        .privileges({"Login"})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+               const std::string& chassisId)
 
-  private:
-    /**
-     * Functions triggers appropriate requests on DBus
-     */
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&,
-               const std::vector<std::string>& params) override
-    {
-        if (params.size() != 1)
-        {
-            messages::internalError(asyncResp->res);
-            return;
-        }
-        const std::string& chassisId = params[0];
-
-        asyncResp->res.jsonValue = {
-            {"@odata.type", "#ActionInfo.v1_1_2.ActionInfo"},
-            {"@odata.id",
-             "/redfish/v1/Chassis/" + chassisId + "/ResetActionInfo"},
-            {"Name", "Reset Action Info"},
-            {"Id", "ResetActionInfo"},
-            {"Parameters",
-             {{{"Name", "ResetType"},
-               {"Required", true},
-               {"DataType", "String"},
-               {"AllowableValues", {"PowerCycle"}}}}}};
-    }
-};
+            {
+                asyncResp->res.jsonValue = {
+                    {"@odata.type", "#ActionInfo.v1_1_2.ActionInfo"},
+                    {"@odata.id",
+                     "/redfish/v1/Chassis/" + chassisId + "/ResetActionInfo"},
+                    {"Name", "Reset Action Info"},
+                    {"Id", "ResetActionInfo"},
+                    {"Parameters",
+                     {{{"Name", "ResetType"},
+                       {"Required", true},
+                       {"DataType", "String"},
+                       {"AllowableValues", {"PowerCycle"}}}}}};
+            });
+}
 
 } // namespace redfish
diff --git a/redfish-core/lib/ethernet.hpp b/redfish-core/lib/ethernet.hpp
index 3e10599..99f452d 100644
--- a/redfish-core/lib/ethernet.hpp
+++ b/redfish-core/lib/ethernet.hpp
@@ -15,6 +15,7 @@
 */
 #pragma once
 
+#include <app.hpp>
 #include <boost/container/flat_map.hpp>
 #include <boost/container/flat_set.hpp>
 #include <dbus_singleton.hpp>
diff --git a/redfish-core/lib/event_service.hpp b/redfish-core/lib/event_service.hpp
index 64a2009..367b6a2 100644
--- a/redfish-core/lib/event_service.hpp
+++ b/redfish-core/lib/event_service.hpp
@@ -16,6 +16,7 @@
 #pragma once
 #include "event_service_manager.hpp"
 
+#include <app.hpp>
 namespace redfish
 {
 
@@ -36,612 +37,572 @@
 
 static constexpr const uint8_t maxNoOfSubscriptions = 20;
 
-class EventService : public Node
+inline void requestRoutesEventService(App& app)
 {
-  public:
-    EventService(App& app) : Node(app, "/redfish/v1/EventService/")
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-    }
+    BMCWEB_ROUTE(app, "/redfish/v1/EventService/")
+        .privileges({"Login"})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                asyncResp->res.jsonValue = {
+                    {"@odata.type", "#EventService.v1_5_0.EventService"},
+                    {"Id", "EventService"},
+                    {"Name", "Event Service"},
+                    {"Subscriptions",
+                     {{"@odata.id", "/redfish/v1/EventService/Subscriptions"}}},
+                    {"Actions",
+                     {{"#EventService.SubmitTestEvent",
+                       {{"target", "/redfish/v1/EventService/Actions/"
+                                   "EventService.SubmitTestEvent"}}}}},
+                    {"@odata.id", "/redfish/v1/EventService"}};
 
-  private:
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&, const std::vector<std::string>&) override
-    {
+                const auto& [enabled, retryAttempts, retryTimeoutInterval] =
+                    EventServiceManager::getInstance().getEventServiceConfig();
 
-        asyncResp->res.jsonValue = {
-            {"@odata.type", "#EventService.v1_5_0.EventService"},
-            {"Id", "EventService"},
-            {"Name", "Event Service"},
-            {"Subscriptions",
-             {{"@odata.id", "/redfish/v1/EventService/Subscriptions"}}},
-            {"Actions",
-             {{"#EventService.SubmitTestEvent",
-               {{"target", "/redfish/v1/EventService/Actions/"
-                           "EventService.SubmitTestEvent"}}}}},
-            {"@odata.id", "/redfish/v1/EventService"}};
+                asyncResp->res.jsonValue["Status"]["State"] =
+                    (enabled ? "Enabled" : "Disabled");
+                asyncResp->res.jsonValue["ServiceEnabled"] = enabled;
+                asyncResp->res.jsonValue["DeliveryRetryAttempts"] =
+                    retryAttempts;
+                asyncResp->res.jsonValue["DeliveryRetryIntervalSeconds"] =
+                    retryTimeoutInterval;
+                asyncResp->res.jsonValue["EventFormatTypes"] =
+                    supportedEvtFormatTypes;
+                asyncResp->res.jsonValue["RegistryPrefixes"] =
+                    supportedRegPrefixes;
+                asyncResp->res.jsonValue["ResourceTypes"] =
+                    supportedResourceTypes;
 
-        const auto& [enabled, retryAttempts, retryTimeoutInterval] =
-            EventServiceManager::getInstance().getEventServiceConfig();
+                nlohmann::json supportedSSEFilters = {
+                    {"EventFormatType", true},        {"MessageId", true},
+                    {"MetricReportDefinition", true}, {"RegistryPrefix", true},
+                    {"OriginResource", false},        {"ResourceType", false}};
 
-        asyncResp->res.jsonValue["Status"]["State"] =
-            (enabled ? "Enabled" : "Disabled");
-        asyncResp->res.jsonValue["ServiceEnabled"] = enabled;
-        asyncResp->res.jsonValue["DeliveryRetryAttempts"] = retryAttempts;
-        asyncResp->res.jsonValue["DeliveryRetryIntervalSeconds"] =
-            retryTimeoutInterval;
-        asyncResp->res.jsonValue["EventFormatTypes"] = supportedEvtFormatTypes;
-        asyncResp->res.jsonValue["RegistryPrefixes"] = supportedRegPrefixes;
-        asyncResp->res.jsonValue["ResourceTypes"] = supportedResourceTypes;
+                asyncResp->res.jsonValue["SSEFilterPropertiesSupported"] =
+                    supportedSSEFilters;
+            });
 
-        nlohmann::json supportedSSEFilters = {
-            {"EventFormatType", true},        {"MessageId", true},
-            {"MetricReportDefinition", true}, {"RegistryPrefix", true},
-            {"OriginResource", false},        {"ResourceType", false}};
+    BMCWEB_ROUTE(app, "/redfish/v1/EventService/")
+        .privileges({"ConfigureManager"})
+        .methods(boost::beast::http::verb::patch)(
+            [](const crow::Request& req,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
 
-        asyncResp->res.jsonValue["SSEFilterPropertiesSupported"] =
-            supportedSSEFilters;
-    }
-
-    void doPatch(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                 const crow::Request& req,
-                 const std::vector<std::string>&) override
-    {
-
-        std::optional<bool> serviceEnabled;
-        std::optional<uint32_t> retryAttemps;
-        std::optional<uint32_t> retryInterval;
-
-        if (!json_util::readJson(req, asyncResp->res, "ServiceEnabled",
-                                 serviceEnabled, "DeliveryRetryAttempts",
-                                 retryAttemps, "DeliveryRetryIntervalSeconds",
-                                 retryInterval))
-        {
-            return;
-        }
-
-        auto [enabled, retryCount, retryTimeoutInterval] =
-            EventServiceManager::getInstance().getEventServiceConfig();
-
-        if (serviceEnabled)
-        {
-            enabled = *serviceEnabled;
-        }
-
-        if (retryAttemps)
-        {
-            // Supported range [1-3]
-            if ((*retryAttemps < 1) || (*retryAttemps > 3))
             {
-                messages::queryParameterOutOfRange(
-                    asyncResp->res, std::to_string(*retryAttemps),
-                    "DeliveryRetryAttempts", "[1-3]");
-            }
-            else
-            {
-                retryCount = *retryAttemps;
-            }
-        }
+                std::optional<bool> serviceEnabled;
+                std::optional<uint32_t> retryAttemps;
+                std::optional<uint32_t> retryInterval;
 
-        if (retryInterval)
-        {
-            // Supported range [30 - 180]
-            if ((*retryInterval < 30) || (*retryInterval > 180))
-            {
-                messages::queryParameterOutOfRange(
-                    asyncResp->res, std::to_string(*retryInterval),
-                    "DeliveryRetryIntervalSeconds", "[30-180]");
-            }
-            else
-            {
-                retryTimeoutInterval = *retryInterval;
-            }
-        }
-
-        EventServiceManager::getInstance().setEventServiceConfig(
-            std::make_tuple(enabled, retryCount, retryTimeoutInterval));
-    }
-};
-
-class SubmitTestEvent : public Node
-{
-  public:
-    SubmitTestEvent(App& app) :
-        Node(app,
-             "/redfish/v1/EventService/Actions/EventService.SubmitTestEvent/")
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-    }
-
-  private:
-    void doPost(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                const crow::Request&, const std::vector<std::string>&) override
-    {
-        EventServiceManager::getInstance().sendTestEventLog();
-        asyncResp->res.result(boost::beast::http::status::no_content);
-    }
-};
-
-class EventDestinationCollection : public Node
-{
-  public:
-    EventDestinationCollection(App& app) :
-        Node(app, "/redfish/v1/EventService/Subscriptions/")
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-    }
-
-  private:
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&, const std::vector<std::string>&) override
-    {
-
-        asyncResp->res.jsonValue = {
-            {"@odata.type",
-             "#EventDestinationCollection.EventDestinationCollection"},
-            {"@odata.id", "/redfish/v1/EventService/Subscriptions"},
-            {"Name", "Event Destination Collections"}};
-
-        nlohmann::json& memberArray = asyncResp->res.jsonValue["Members"];
-
-        std::vector<std::string> subscripIds =
-            EventServiceManager::getInstance().getAllIDs();
-        memberArray = nlohmann::json::array();
-        asyncResp->res.jsonValue["Members@odata.count"] = subscripIds.size();
-
-        for (const std::string& id : subscripIds)
-        {
-            memberArray.push_back(
-                {{"@odata.id",
-                  "/redfish/v1/EventService/Subscriptions/" + id}});
-        }
-    }
-
-    void doPost(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                const crow::Request& req,
-                const std::vector<std::string>&) override
-    {
-
-        if (EventServiceManager::getInstance().getNumberOfSubscriptions() >=
-            maxNoOfSubscriptions)
-        {
-            messages::eventSubscriptionLimitExceeded(asyncResp->res);
-            return;
-        }
-        std::string destUrl;
-        std::string protocol;
-        std::optional<std::string> context;
-        std::optional<std::string> subscriptionType;
-        std::optional<std::string> eventFormatType2;
-        std::optional<std::string> retryPolicy;
-        std::optional<std::vector<std::string>> msgIds;
-        std::optional<std::vector<std::string>> regPrefixes;
-        std::optional<std::vector<std::string>> resTypes;
-        std::optional<std::vector<nlohmann::json>> headers;
-        std::optional<std::vector<nlohmann::json>> mrdJsonArray;
-
-        if (!json_util::readJson(
-                req, asyncResp->res, "Destination", destUrl, "Context", context,
-                "Protocol", protocol, "SubscriptionType", subscriptionType,
-                "EventFormatType", eventFormatType2, "HttpHeaders", headers,
-                "RegistryPrefixes", regPrefixes, "MessageIds", msgIds,
-                "DeliveryRetryPolicy", retryPolicy, "MetricReportDefinitions",
-                mrdJsonArray, "ResourceTypes", resTypes))
-        {
-            return;
-        }
-
-        if (regPrefixes && msgIds)
-        {
-            if (regPrefixes->size() && msgIds->size())
-            {
-                messages::mutualExclusiveProperties(
-                    asyncResp->res, "RegistryPrefixes", "MessageIds");
-                return;
-            }
-        }
-
-        // Validate the URL using regex expression
-        // Format: <protocol>://<host>:<port>/<uri>
-        // protocol: http/https
-        // host: Exclude ' ', ':', '#', '?'
-        // port: Empty or numeric value with ':' separator.
-        // uri: Start with '/' and Exclude '#', ' '
-        //      Can include query params(ex: '/event?test=1')
-        // TODO: Need to validate hostname extensively(as per rfc)
-        const std::regex urlRegex(
-            "(http|https)://([^/\\x20\\x3f\\x23\\x3a]+):?([0-9]*)(/"
-            "([^\\x20\\x23\\x3f]*\\x3f?([^\\x20\\x23\\x3f])*)?)");
-        std::cmatch match;
-        if (!std::regex_match(destUrl.c_str(), match, urlRegex))
-        {
-            messages::propertyValueFormatError(asyncResp->res, destUrl,
-                                               "Destination");
-            return;
-        }
-
-        std::string uriProto = std::string(match[1].first, match[1].second);
-        if (uriProto == "http")
-        {
-#ifndef BMCWEB_INSECURE_ENABLE_HTTP_PUSH_STYLE_EVENTING
-            messages::propertyValueFormatError(asyncResp->res, destUrl,
-                                               "Destination");
-            return;
-#endif
-        }
-
-        std::string host = std::string(match[2].first, match[2].second);
-        std::string port = std::string(match[3].first, match[3].second);
-        std::string path = std::string(match[4].first, match[4].second);
-        if (port.empty())
-        {
-            if (uriProto == "http")
-            {
-                port = "80";
-            }
-            else
-            {
-                port = "443";
-            }
-        }
-        if (path.empty())
-        {
-            path = "/";
-        }
-
-        std::shared_ptr<Subscription> subValue =
-            std::make_shared<Subscription>(host, port, path, uriProto);
-
-        subValue->destinationUrl = destUrl;
-
-        if (subscriptionType)
-        {
-            if (*subscriptionType != "RedfishEvent")
-            {
-                messages::propertyValueNotInList(
-                    asyncResp->res, *subscriptionType, "SubscriptionType");
-                return;
-            }
-            subValue->subscriptionType = *subscriptionType;
-        }
-        else
-        {
-            subValue->subscriptionType = "RedfishEvent"; // Default
-        }
-
-        if (protocol != "Redfish")
-        {
-            messages::propertyValueNotInList(asyncResp->res, protocol,
-                                             "Protocol");
-            return;
-        }
-        subValue->protocol = protocol;
-
-        if (eventFormatType2)
-        {
-            if (std::find(supportedEvtFormatTypes.begin(),
-                          supportedEvtFormatTypes.end(),
-                          *eventFormatType2) == supportedEvtFormatTypes.end())
-            {
-                messages::propertyValueNotInList(
-                    asyncResp->res, *eventFormatType2, "EventFormatType");
-                return;
-            }
-            subValue->eventFormatType = *eventFormatType2;
-        }
-        else
-        {
-            // If not specified, use default "Event"
-            subValue->eventFormatType = "Event";
-        }
-
-        if (context)
-        {
-            subValue->customText = *context;
-        }
-
-        if (headers)
-        {
-            subValue->httpHeaders = *headers;
-        }
-
-        if (regPrefixes)
-        {
-            for (const std::string& it : *regPrefixes)
-            {
-                if (std::find(supportedRegPrefixes.begin(),
-                              supportedRegPrefixes.end(),
-                              it) == supportedRegPrefixes.end())
+                if (!json_util::readJson(
+                        req, asyncResp->res, "ServiceEnabled", serviceEnabled,
+                        "DeliveryRetryAttempts", retryAttemps,
+                        "DeliveryRetryIntervalSeconds", retryInterval))
                 {
-                    messages::propertyValueNotInList(asyncResp->res, it,
-                                                     "RegistryPrefixes");
                     return;
                 }
-            }
-            subValue->registryPrefixes = *regPrefixes;
-        }
 
-        if (resTypes)
-        {
-            for (const std::string& it : *resTypes)
-            {
-                if (std::find(supportedResourceTypes.begin(),
-                              supportedResourceTypes.end(),
-                              it) == supportedResourceTypes.end())
+                auto [enabled, retryCount, retryTimeoutInterval] =
+                    EventServiceManager::getInstance().getEventServiceConfig();
+
+                if (serviceEnabled)
                 {
-                    messages::propertyValueNotInList(asyncResp->res, it,
-                                                     "ResourceTypes");
-                    return;
+                    enabled = *serviceEnabled;
                 }
-            }
-            subValue->resourceTypes = *resTypes;
-        }
 
-        if (msgIds)
-        {
-            std::vector<std::string> registryPrefix;
-
-            // If no registry prefixes are mentioned, consider all supported
-            // prefixes
-            if (subValue->registryPrefixes.empty())
-            {
-                registryPrefix.assign(supportedRegPrefixes.begin(),
-                                      supportedRegPrefixes.end());
-            }
-            else
-            {
-                registryPrefix = subValue->registryPrefixes;
-            }
-
-            for (const std::string& id : *msgIds)
-            {
-                bool validId = false;
-
-                // Check for Message ID in each of the selected Registry
-                for (const std::string& it : registryPrefix)
+                if (retryAttemps)
                 {
-                    const boost::beast::span<
-                        const redfish::message_registries::MessageEntry>
-                        registry =
-                            redfish::message_registries::getRegistryFromPrefix(
-                                it);
-
-                    if (std::any_of(
-                            registry.cbegin(), registry.cend(),
-                            [&id](
-                                const redfish::message_registries::MessageEntry&
-                                    messageEntry) {
-                                return !id.compare(messageEntry.first);
-                            }))
+                    // Supported range [1-3]
+                    if ((*retryAttemps < 1) || (*retryAttemps > 3))
                     {
-                        validId = true;
-                        break;
+                        messages::queryParameterOutOfRange(
+                            asyncResp->res, std::to_string(*retryAttemps),
+                            "DeliveryRetryAttempts", "[1-3]");
+                    }
+                    else
+                    {
+                        retryCount = *retryAttemps;
                     }
                 }
 
-                if (!validId)
+                if (retryInterval)
                 {
-                    messages::propertyValueNotInList(asyncResp->res, id,
-                                                     "MessageIds");
+                    // Supported range [30 - 180]
+                    if ((*retryInterval < 30) || (*retryInterval > 180))
+                    {
+                        messages::queryParameterOutOfRange(
+                            asyncResp->res, std::to_string(*retryInterval),
+                            "DeliveryRetryIntervalSeconds", "[30-180]");
+                    }
+                    else
+                    {
+                        retryTimeoutInterval = *retryInterval;
+                    }
+                }
+
+                EventServiceManager::getInstance().setEventServiceConfig(
+                    std::make_tuple(enabled, retryCount, retryTimeoutInterval));
+            });
+}
+
+inline void requestRoutesSubmitTestEvent(App& app)
+{
+
+    BMCWEB_ROUTE(
+        app, "/redfish/v1/EventService/Actions/EventService.SubmitTestEvent/")
+        .privileges({"ConfigureManager"})
+        .methods(boost::beast::http::verb::post)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                EventServiceManager::getInstance().sendTestEventLog();
+                asyncResp->res.result(boost::beast::http::status::no_content);
+            });
+}
+
+inline void requestRoutesEventDestinationCollection(App& app)
+{
+    BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions")
+        .privileges({"Login"})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                asyncResp->res.jsonValue = {
+                    {"@odata.type",
+                     "#EventDestinationCollection.EventDestinationCollection"},
+                    {"@odata.id", "/redfish/v1/EventService/Subscriptions"},
+                    {"Name", "Event Destination Collections"}};
+
+                nlohmann::json& memberArray =
+                    asyncResp->res.jsonValue["Members"];
+
+                std::vector<std::string> subscripIds =
+                    EventServiceManager::getInstance().getAllIDs();
+                memberArray = nlohmann::json::array();
+                asyncResp->res.jsonValue["Members@odata.count"] =
+                    subscripIds.size();
+
+                for (const std::string& id : subscripIds)
+                {
+                    memberArray.push_back(
+                        {{"@odata.id",
+                          "/redfish/v1/EventService/Subscriptions/" + id}});
+                }
+            });
+    BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/")
+        .privileges({"ConfigureManager"})
+        .methods(boost::beast::http::verb::post)(
+            [](const crow::Request& req,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                if (EventServiceManager::getInstance()
+                        .getNumberOfSubscriptions() >= maxNoOfSubscriptions)
+                {
+                    messages::eventSubscriptionLimitExceeded(asyncResp->res);
                     return;
                 }
-            }
+                std::string destUrl;
+                std::string protocol;
+                std::optional<std::string> context;
+                std::optional<std::string> subscriptionType;
+                std::optional<std::string> eventFormatType2;
+                std::optional<std::string> retryPolicy;
+                std::optional<std::vector<std::string>> msgIds;
+                std::optional<std::vector<std::string>> regPrefixes;
+                std::optional<std::vector<std::string>> resTypes;
+                std::optional<std::vector<nlohmann::json>> headers;
+                std::optional<std::vector<nlohmann::json>> mrdJsonArray;
 
-            subValue->registryMsgIds = *msgIds;
-        }
-
-        if (retryPolicy)
-        {
-            if (std::find(supportedRetryPolicies.begin(),
-                          supportedRetryPolicies.end(),
-                          *retryPolicy) == supportedRetryPolicies.end())
-            {
-                messages::propertyValueNotInList(asyncResp->res, *retryPolicy,
-                                                 "DeliveryRetryPolicy");
-                return;
-            }
-            subValue->retryPolicy = *retryPolicy;
-        }
-        else
-        {
-            // Default "TerminateAfterRetries"
-            subValue->retryPolicy = "TerminateAfterRetries";
-        }
-
-        if (mrdJsonArray)
-        {
-            for (nlohmann::json& mrdObj : *mrdJsonArray)
-            {
-                std::string mrdUri;
-                if (json_util::getValueFromJsonObject(mrdObj, "@odata.id",
-                                                      mrdUri))
+                if (!json_util::readJson(
+                        req, asyncResp->res, "Destination", destUrl, "Context",
+                        context, "Protocol", protocol, "SubscriptionType",
+                        subscriptionType, "EventFormatType", eventFormatType2,
+                        "HttpHeaders", headers, "RegistryPrefixes", regPrefixes,
+                        "MessageIds", msgIds, "DeliveryRetryPolicy",
+                        retryPolicy, "MetricReportDefinitions", mrdJsonArray,
+                        "ResourceTypes", resTypes))
                 {
-                    subValue->metricReportDefinitions.emplace_back(mrdUri);
+                    return;
+                }
+
+                if (regPrefixes && msgIds)
+                {
+                    if (regPrefixes->size() && msgIds->size())
+                    {
+                        messages::mutualExclusiveProperties(
+                            asyncResp->res, "RegistryPrefixes", "MessageIds");
+                        return;
+                    }
+                }
+
+                // Validate the URL using regex expression
+                // Format: <protocol>://<host>:<port>/<uri>
+                // protocol: http/https
+                // host: Exclude ' ', ':', '#', '?'
+                // port: Empty or numeric value with ':' separator.
+                // uri: Start with '/' and Exclude '#', ' '
+                //      Can include query params(ex: '/event?test=1')
+                // TODO: Need to validate hostname extensively(as per rfc)
+                const std::regex urlRegex(
+                    "(http|https)://([^/\\x20\\x3f\\x23\\x3a]+):?([0-9]*)(/"
+                    "([^\\x20\\x23\\x3f]*\\x3f?([^\\x20\\x23\\x3f])*)?)");
+                std::cmatch match;
+                if (!std::regex_match(destUrl.c_str(), match, urlRegex))
+                {
+                    messages::propertyValueFormatError(asyncResp->res, destUrl,
+                                                       "Destination");
+                    return;
+                }
+
+                std::string uriProto =
+                    std::string(match[1].first, match[1].second);
+                if (uriProto == "http")
+                {
+#ifndef BMCWEB_INSECURE_ENABLE_HTTP_PUSH_STYLE_EVENTING
+                    messages::propertyValueFormatError(asyncResp->res, destUrl,
+                                                       "Destination");
+                    return;
+#endif
+                }
+
+                std::string host = std::string(match[2].first, match[2].second);
+                std::string port = std::string(match[3].first, match[3].second);
+                std::string path = std::string(match[4].first, match[4].second);
+                if (port.empty())
+                {
+                    if (uriProto == "http")
+                    {
+                        port = "80";
+                    }
+                    else
+                    {
+                        port = "443";
+                    }
+                }
+                if (path.empty())
+                {
+                    path = "/";
+                }
+
+                std::shared_ptr<Subscription> subValue =
+                    std::make_shared<Subscription>(host, port, path, uriProto);
+
+                subValue->destinationUrl = destUrl;
+
+                if (subscriptionType)
+                {
+                    if (*subscriptionType != "RedfishEvent")
+                    {
+                        messages::propertyValueNotInList(asyncResp->res,
+                                                         *subscriptionType,
+                                                         "SubscriptionType");
+                        return;
+                    }
+                    subValue->subscriptionType = *subscriptionType;
                 }
                 else
                 {
-                    messages::propertyValueFormatError(
-                        asyncResp->res,
-                        mrdObj.dump(2, ' ', true,
-                                    nlohmann::json::error_handler_t::replace),
-                        "MetricReportDefinitions");
+                    subValue->subscriptionType = "RedfishEvent"; // Default
+                }
+
+                if (protocol != "Redfish")
+                {
+                    messages::propertyValueNotInList(asyncResp->res, protocol,
+                                                     "Protocol");
                     return;
                 }
-            }
-        }
+                subValue->protocol = protocol;
 
-        std::string id =
-            EventServiceManager::getInstance().addSubscription(subValue);
-        if (id.empty())
-        {
-            messages::internalError(asyncResp->res);
-            return;
-        }
+                if (eventFormatType2)
+                {
+                    if (std::find(supportedEvtFormatTypes.begin(),
+                                  supportedEvtFormatTypes.end(),
+                                  *eventFormatType2) ==
+                        supportedEvtFormatTypes.end())
+                    {
+                        messages::propertyValueNotInList(asyncResp->res,
+                                                         *eventFormatType2,
+                                                         "EventFormatType");
+                        return;
+                    }
+                    subValue->eventFormatType = *eventFormatType2;
+                }
+                else
+                {
+                    // If not specified, use default "Event"
+                    subValue->eventFormatType = "Event";
+                }
 
-        messages::created(asyncResp->res);
-        asyncResp->res.addHeader(
-            "Location", "/redfish/v1/EventService/Subscriptions/" + id);
-    }
-};
+                if (context)
+                {
+                    subValue->customText = *context;
+                }
 
-class EventDestination : public Node
+                if (headers)
+                {
+                    subValue->httpHeaders = *headers;
+                }
+
+                if (regPrefixes)
+                {
+                    for (const std::string& it : *regPrefixes)
+                    {
+                        if (std::find(supportedRegPrefixes.begin(),
+                                      supportedRegPrefixes.end(),
+                                      it) == supportedRegPrefixes.end())
+                        {
+                            messages::propertyValueNotInList(
+                                asyncResp->res, it, "RegistryPrefixes");
+                            return;
+                        }
+                    }
+                    subValue->registryPrefixes = *regPrefixes;
+                }
+
+                if (resTypes)
+                {
+                    for (const std::string& it : *resTypes)
+                    {
+                        if (std::find(supportedResourceTypes.begin(),
+                                      supportedResourceTypes.end(),
+                                      it) == supportedResourceTypes.end())
+                        {
+                            messages::propertyValueNotInList(asyncResp->res, it,
+                                                             "ResourceTypes");
+                            return;
+                        }
+                    }
+                    subValue->resourceTypes = *resTypes;
+                }
+
+                if (msgIds)
+                {
+                    std::vector<std::string> registryPrefix;
+
+                    // If no registry prefixes are mentioned, consider all
+                    // supported prefixes
+                    if (subValue->registryPrefixes.empty())
+                    {
+                        registryPrefix.assign(supportedRegPrefixes.begin(),
+                                              supportedRegPrefixes.end());
+                    }
+                    else
+                    {
+                        registryPrefix = subValue->registryPrefixes;
+                    }
+
+                    for (const std::string& id : *msgIds)
+                    {
+                        bool validId = false;
+
+                        // Check for Message ID in each of the selected Registry
+                        for (const std::string& it : registryPrefix)
+                        {
+                            const boost::beast::span<
+                                const redfish::message_registries::MessageEntry>
+                                registry = redfish::message_registries::
+                                    getRegistryFromPrefix(it);
+
+                            if (std::any_of(
+                                    registry.cbegin(), registry.cend(),
+                                    [&id](const redfish::message_registries::
+                                              MessageEntry& messageEntry) {
+                                        return !id.compare(messageEntry.first);
+                                    }))
+                            {
+                                validId = true;
+                                break;
+                            }
+                        }
+
+                        if (!validId)
+                        {
+                            messages::propertyValueNotInList(asyncResp->res, id,
+                                                             "MessageIds");
+                            return;
+                        }
+                    }
+
+                    subValue->registryMsgIds = *msgIds;
+                }
+
+                if (retryPolicy)
+                {
+                    if (std::find(supportedRetryPolicies.begin(),
+                                  supportedRetryPolicies.end(),
+                                  *retryPolicy) == supportedRetryPolicies.end())
+                    {
+                        messages::propertyValueNotInList(asyncResp->res,
+                                                         *retryPolicy,
+                                                         "DeliveryRetryPolicy");
+                        return;
+                    }
+                    subValue->retryPolicy = *retryPolicy;
+                }
+                else
+                {
+                    // Default "TerminateAfterRetries"
+                    subValue->retryPolicy = "TerminateAfterRetries";
+                }
+
+                if (mrdJsonArray)
+                {
+                    for (nlohmann::json& mrdObj : *mrdJsonArray)
+                    {
+                        std::string mrdUri;
+                        if (json_util::getValueFromJsonObject(
+                                mrdObj, "@odata.id", mrdUri))
+                        {
+                            subValue->metricReportDefinitions.emplace_back(
+                                mrdUri);
+                        }
+                        else
+                        {
+                            messages::propertyValueFormatError(
+                                asyncResp->res,
+                                mrdObj.dump(
+                                    2, ' ', true,
+                                    nlohmann::json::error_handler_t::replace),
+                                "MetricReportDefinitions");
+                            return;
+                        }
+                    }
+                }
+
+                std::string id =
+                    EventServiceManager::getInstance().addSubscription(
+                        subValue);
+                if (id.empty())
+                {
+                    messages::internalError(asyncResp->res);
+                    return;
+                }
+
+                messages::created(asyncResp->res);
+                asyncResp->res.addHeader(
+                    "Location", "/redfish/v1/EventService/Subscriptions/" + id);
+            });
+}
+
+inline void requestRoutesEventDestination(App& app)
 {
-  public:
-    EventDestination(App& app) :
-        Node(app, "/redfish/v1/EventService/Subscriptions/<str>/",
-             std::string())
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-    }
+    BMCWEB_ROUTE(app, "redfish/v1/EventService/Subscriptions/<str>/")
+        .privileges({"Login"})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+               const std::string& param) {
+                std::shared_ptr<Subscription> subValue =
+                    EventServiceManager::getInstance().getSubscription(param);
+                if (subValue == nullptr)
+                {
+                    asyncResp->res.result(
+                        boost::beast::http::status::not_found);
+                    return;
+                }
+                const std::string& id = param;
 
-  private:
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&,
-               const std::vector<std::string>& params) override
-    {
+                asyncResp->res.jsonValue = {
+                    {"@odata.type",
+                     "#EventDestination.v1_7_0.EventDestination"},
+                    {"Protocol", "Redfish"}};
+                asyncResp->res.jsonValue["@odata.id"] =
+                    "/redfish/v1/EventService/Subscriptions/" + id;
+                asyncResp->res.jsonValue["Id"] = id;
+                asyncResp->res.jsonValue["Name"] = "Event Destination " + id;
+                asyncResp->res.jsonValue["Destination"] =
+                    subValue->destinationUrl;
+                asyncResp->res.jsonValue["Context"] = subValue->customText;
+                asyncResp->res.jsonValue["SubscriptionType"] =
+                    subValue->subscriptionType;
+                asyncResp->res.jsonValue["HttpHeaders"] = subValue->httpHeaders;
+                asyncResp->res.jsonValue["EventFormatType"] =
+                    subValue->eventFormatType;
+                asyncResp->res.jsonValue["RegistryPrefixes"] =
+                    subValue->registryPrefixes;
+                asyncResp->res.jsonValue["ResourceTypes"] =
+                    subValue->resourceTypes;
 
-        if (params.size() != 1)
-        {
-            messages::internalError(asyncResp->res);
-            return;
-        }
+                asyncResp->res.jsonValue["MessageIds"] =
+                    subValue->registryMsgIds;
+                asyncResp->res.jsonValue["DeliveryRetryPolicy"] =
+                    subValue->retryPolicy;
 
-        std::shared_ptr<Subscription> subValue =
-            EventServiceManager::getInstance().getSubscription(params[0]);
-        if (subValue == nullptr)
-        {
-            asyncResp->res.result(boost::beast::http::status::not_found);
-            return;
-        }
-        const std::string& id = params[0];
+                std::vector<nlohmann::json> mrdJsonArray;
+                for (const auto& mdrUri : subValue->metricReportDefinitions)
+                {
+                    mrdJsonArray.push_back({{"@odata.id", mdrUri}});
+                }
+                asyncResp->res.jsonValue["MetricReportDefinitions"] =
+                    mrdJsonArray;
+            });
+    /////redfish/v1/EventService/Subscriptions/
+    // ConfigureManager
+    BMCWEB_ROUTE(app, "redfish/v1/EventService/Subscriptions/<str>/")
+        .privileges({"ConfigureManager"})
+        .methods(boost::beast::http::verb::patch)(
+            [](const crow::Request& req,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+               const std::string& param) {
+                std::shared_ptr<Subscription> subValue =
+                    EventServiceManager::getInstance().getSubscription(param);
+                if (subValue == nullptr)
+                {
+                    asyncResp->res.result(
+                        boost::beast::http::status::not_found);
+                    return;
+                }
 
-        asyncResp->res.jsonValue = {
-            {"@odata.type", "#EventDestination.v1_7_0.EventDestination"},
-            {"Protocol", "Redfish"}};
-        asyncResp->res.jsonValue["@odata.id"] =
-            "/redfish/v1/EventService/Subscriptions/" + id;
-        asyncResp->res.jsonValue["Id"] = id;
-        asyncResp->res.jsonValue["Name"] = "Event Destination " + id;
-        asyncResp->res.jsonValue["Destination"] = subValue->destinationUrl;
-        asyncResp->res.jsonValue["Context"] = subValue->customText;
-        asyncResp->res.jsonValue["SubscriptionType"] =
-            subValue->subscriptionType;
-        asyncResp->res.jsonValue["HttpHeaders"] = subValue->httpHeaders;
-        asyncResp->res.jsonValue["EventFormatType"] = subValue->eventFormatType;
-        asyncResp->res.jsonValue["RegistryPrefixes"] =
-            subValue->registryPrefixes;
-        asyncResp->res.jsonValue["ResourceTypes"] = subValue->resourceTypes;
+                std::optional<std::string> context;
+                std::optional<std::string> retryPolicy;
+                std::optional<std::vector<nlohmann::json>> headers;
 
-        asyncResp->res.jsonValue["MessageIds"] = subValue->registryMsgIds;
-        asyncResp->res.jsonValue["DeliveryRetryPolicy"] = subValue->retryPolicy;
+                if (!json_util::readJson(req, asyncResp->res, "Context",
+                                         context, "DeliveryRetryPolicy",
+                                         retryPolicy, "HttpHeaders", headers))
+                {
+                    return;
+                }
 
-        std::vector<nlohmann::json> mrdJsonArray;
-        for (const auto& mdrUri : subValue->metricReportDefinitions)
-        {
-            mrdJsonArray.push_back({{"@odata.id", mdrUri}});
-        }
-        asyncResp->res.jsonValue["MetricReportDefinitions"] = mrdJsonArray;
-    }
+                if (context)
+                {
+                    subValue->customText = *context;
+                }
 
-    void doPatch(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                 const crow::Request& req,
-                 const std::vector<std::string>& params) override
-    {
+                if (headers)
+                {
+                    subValue->httpHeaders = *headers;
+                }
 
-        if (params.size() != 1)
-        {
-            messages::internalError(asyncResp->res);
-            return;
-        }
+                if (retryPolicy)
+                {
+                    if (std::find(supportedRetryPolicies.begin(),
+                                  supportedRetryPolicies.end(),
+                                  *retryPolicy) == supportedRetryPolicies.end())
+                    {
+                        messages::propertyValueNotInList(asyncResp->res,
+                                                         *retryPolicy,
+                                                         "DeliveryRetryPolicy");
+                        return;
+                    }
+                    subValue->retryPolicy = *retryPolicy;
+                    subValue->updateRetryPolicy();
+                }
 
-        std::shared_ptr<Subscription> subValue =
-            EventServiceManager::getInstance().getSubscription(params[0]);
-        if (subValue == nullptr)
-        {
-            asyncResp->res.result(boost::beast::http::status::not_found);
-            return;
-        }
-
-        std::optional<std::string> context;
-        std::optional<std::string> retryPolicy;
-        std::optional<std::vector<nlohmann::json>> headers;
-
-        if (!json_util::readJson(req, asyncResp->res, "Context", context,
-                                 "DeliveryRetryPolicy", retryPolicy,
-                                 "HttpHeaders", headers))
-        {
-            return;
-        }
-
-        if (context)
-        {
-            subValue->customText = *context;
-        }
-
-        if (headers)
-        {
-            subValue->httpHeaders = *headers;
-        }
-
-        if (retryPolicy)
-        {
-            if (std::find(supportedRetryPolicies.begin(),
-                          supportedRetryPolicies.end(),
-                          *retryPolicy) == supportedRetryPolicies.end())
-            {
-                messages::propertyValueNotInList(asyncResp->res, *retryPolicy,
-                                                 "DeliveryRetryPolicy");
-                return;
-            }
-            subValue->retryPolicy = *retryPolicy;
-            subValue->updateRetryPolicy();
-        }
-
-        EventServiceManager::getInstance().updateSubscriptionData();
-    }
-
-    void doDelete(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                  const crow::Request&,
-                  const std::vector<std::string>& params) override
-    {
-
-        if (params.size() != 1)
-        {
-            messages::internalError(asyncResp->res);
-            return;
-        }
-
-        if (!EventServiceManager::getInstance().isSubscriptionExist(params[0]))
-        {
-            asyncResp->res.result(boost::beast::http::status::not_found);
-            return;
-        }
-        EventServiceManager::getInstance().deleteSubscription(params[0]);
-    }
-};
+                EventServiceManager::getInstance().updateSubscriptionData();
+            });
+    BMCWEB_ROUTE(app, "redfish/v1/EventService/Subscriptions/<str>/")
+        .privileges({"ConfigureManager"})
+        .methods(boost::beast::http::verb::delete_)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+               const std::string& param) {
+                if (!EventServiceManager::getInstance().isSubscriptionExist(
+                        param))
+                {
+                    asyncResp->res.result(
+                        boost::beast::http::status::not_found);
+                    return;
+                }
+                EventServiceManager::getInstance().deleteSubscription(param);
+            });
+}
 
 } // namespace redfish
diff --git a/redfish-core/lib/health.hpp b/redfish-core/lib/health.hpp
index cd4faa4..7dbab69 100644
--- a/redfish-core/lib/health.hpp
+++ b/redfish-core/lib/health.hpp
@@ -17,6 +17,7 @@
 
 #include "async_resp.hpp"
 
+#include <app.hpp>
 #include <boost/algorithm/string/predicate.hpp>
 #include <boost/container/flat_set.hpp>
 #include <dbus_singleton.hpp>
diff --git a/redfish-core/lib/hypervisor_system.hpp b/redfish-core/lib/hypervisor_system.hpp
index 4a3a205..4c85b62 100644
--- a/redfish-core/lib/hypervisor_system.hpp
+++ b/redfish-core/lib/hypervisor_system.hpp
@@ -1,5 +1,6 @@
 #pragma once
 
+#include <app.hpp>
 #include <boost/container/flat_map.hpp>
 #include <boost/container/flat_set.hpp>
 #include <dbus_singleton.hpp>
@@ -149,137 +150,6 @@
         std::array<const char*, 1>{"xyz.openbmc_project.State.Host"});
 }
 
-/**
- * Hypervisor Systems derived class for delivering Computer Systems Schema.
- */
-class HypervisorSystem : public Node
-{
-  public:
-    /*
-     * Default Constructor
-     */
-    HypervisorSystem(App& app) : Node(app, "/redfish/v1/Systems/hypervisor/")
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureComponents"}}}};
-    }
-
-  private:
-    /**
-     * Functions triggers appropriate requests on DBus
-     */
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&, const std::vector<std::string>&) override
-    {
-        crow::connections::systemBus->async_method_call(
-            [asyncResp](const boost::system::error_code ec,
-                        const std::variant<std::string>& /*hostName*/) {
-                if (ec)
-                {
-                    messages::resourceNotFound(asyncResp->res, "System",
-                                               "hypervisor");
-                    return;
-                }
-                BMCWEB_LOG_DEBUG << "Hypervisor is available";
-
-                asyncResp->res.jsonValue["@odata.type"] =
-                    "#ComputerSystem.v1_6_0.ComputerSystem";
-                asyncResp->res.jsonValue["@odata.id"] =
-                    "/redfish/v1/Systems/hypervisor";
-                asyncResp->res.jsonValue["Description"] = "Hypervisor";
-                asyncResp->res.jsonValue["Name"] = "Hypervisor";
-                asyncResp->res.jsonValue["Id"] = "hypervisor";
-                asyncResp->res.jsonValue["Links"]["ManagedBy"] = {
-                    {{"@odata.id", "/redfish/v1/Managers/bmc"}}};
-                asyncResp->res.jsonValue["EthernetInterfaces"] = {
-                    {"@odata.id", "/redfish/v1/Systems/hypervisor/"
-                                  "EthernetInterfaces"}};
-                getHypervisorState(asyncResp);
-                getHypervisorActions(asyncResp);
-                // TODO: Add "SystemType" : "hypervisor"
-            },
-            "xyz.openbmc_project.Settings",
-            "/xyz/openbmc_project/network/hypervisor",
-            "org.freedesktop.DBus.Properties", "Get",
-            "xyz.openbmc_project.Network.SystemConfiguration", "HostName");
-    }
-};
-
-/**
- * HypervisorInterfaceCollection class to handle the GET and PATCH on Hypervisor
- * Interface
- */
-class HypervisorInterfaceCollection : public Node
-{
-  public:
-    HypervisorInterfaceCollection(App& app) :
-        Node(app, "/redfish/v1/Systems/hypervisor/EthernetInterfaces/")
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureComponents"}}}};
-    }
-
-  private:
-    /**
-     * Functions triggers appropriate requests on DBus
-     */
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&, const std::vector<std::string>&) override
-    {
-        const std::array<const char*, 1> interfaces = {
-            "xyz.openbmc_project.Network.EthernetInterface"};
-
-        crow::connections::systemBus->async_method_call(
-            [asyncResp](const boost::system::error_code error,
-                        const std::vector<std::string>& ifaceList) {
-                if (error)
-                {
-                    messages::resourceNotFound(asyncResp->res, "System",
-                                               "hypervisor");
-                    return;
-                }
-                asyncResp->res.jsonValue["@odata.type"] =
-                    "#EthernetInterfaceCollection."
-                    "EthernetInterfaceCollection";
-                asyncResp->res.jsonValue["@odata.id"] =
-                    "/redfish/v1/Systems/hypervisor/EthernetInterfaces";
-                asyncResp->res.jsonValue["Name"] = "Hypervisor Ethernet "
-                                                   "Interface Collection";
-                asyncResp->res.jsonValue["Description"] =
-                    "Collection of Virtual Management "
-                    "Interfaces for the hypervisor";
-
-                nlohmann::json& ifaceArray =
-                    asyncResp->res.jsonValue["Members"];
-                ifaceArray = nlohmann::json::array();
-                for (const std::string& iface : ifaceList)
-                {
-                    sdbusplus::message::object_path path(iface);
-                    std::string name = path.filename();
-                    if (name.empty())
-                    {
-                        continue;
-                    }
-
-                    ifaceArray.push_back(
-                        {{"@odata.id", "/redfish/v1/Systems/hypervisor/"
-                                       "EthernetInterfaces/" +
-                                           name}});
-                }
-                asyncResp->res.jsonValue["Members@odata.count"] =
-                    ifaceArray.size();
-            },
-            "xyz.openbmc_project.ObjectMapper",
-            "/xyz/openbmc_project/object_mapper",
-            "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths",
-            "/xyz/openbmc_project/network/hypervisor", 0, interfaces);
-    }
-};
-
 inline bool extractHypervisorInterfaceData(
     const std::string& ethIfaceId, const GetManagedObjects& dbusData,
     EthernetInterfaceData& ethData,
@@ -601,600 +471,636 @@
     setHypervisorIPv4Subnet(asyncResp, ifaceId, prefixLength);
 }
 
-/**
- * HypervisorInterface derived class for delivering Ethernet Schema
- */
-class HypervisorInterface : public Node
+inline void parseInterfaceData(
+    nlohmann::json& jsonResponse, const std::string& ifaceId,
+    const EthernetInterfaceData& ethData,
+    const boost::container::flat_set<IPv4AddressData>& ipv4Data)
 {
-  public:
-    /*
-     * Default Constructor
-     */
-    HypervisorInterface(App& app) :
-        Node(app, "/redfish/v1/Systems/hypervisor/EthernetInterfaces/<str>/",
-             std::string())
+    jsonResponse["Id"] = ifaceId;
+    jsonResponse["@odata.id"] =
+        "/redfish/v1/Systems/hypervisor/EthernetInterfaces/" + ifaceId;
+    jsonResponse["InterfaceEnabled"] = true;
+    jsonResponse["MACAddress"] = ethData.mac_address;
+
+    jsonResponse["HostName"] = ethData.hostname;
+    jsonResponse["DHCPv4"]["DHCPEnabled"] =
+        translateDHCPEnabledToBool(ethData.DHCPEnabled, true);
+
+    nlohmann::json& ipv4Array = jsonResponse["IPv4Addresses"];
+    nlohmann::json& ipv4StaticArray = jsonResponse["IPv4StaticAddresses"];
+    ipv4Array = nlohmann::json::array();
+    ipv4StaticArray = nlohmann::json::array();
+    for (auto& ipv4Config : ipv4Data)
     {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureComponents"}}}};
-    }
-
-  private:
-    void parseInterfaceData(
-        nlohmann::json& jsonResponse, const std::string& ifaceId,
-        const EthernetInterfaceData& ethData,
-        const boost::container::flat_set<IPv4AddressData>& ipv4Data)
-    {
-        jsonResponse["Id"] = ifaceId;
-        jsonResponse["@odata.id"] =
-            "/redfish/v1/Systems/hypervisor/EthernetInterfaces/" + ifaceId;
-        jsonResponse["InterfaceEnabled"] = true;
-        jsonResponse["MACAddress"] = ethData.mac_address;
-
-        jsonResponse["HostName"] = ethData.hostname;
-        jsonResponse["DHCPv4"]["DHCPEnabled"] =
-            translateDHCPEnabledToBool(ethData.DHCPEnabled, true);
-
-        nlohmann::json& ipv4Array = jsonResponse["IPv4Addresses"];
-        nlohmann::json& ipv4StaticArray = jsonResponse["IPv4StaticAddresses"];
-        ipv4Array = nlohmann::json::array();
-        ipv4StaticArray = nlohmann::json::array();
-        for (auto& ipv4Config : ipv4Data)
+        if (ipv4Config.isActive)
         {
-            if (ipv4Config.isActive)
-            {
 
-                ipv4Array.push_back({{"AddressOrigin", ipv4Config.origin},
-                                     {"SubnetMask", ipv4Config.netmask},
-                                     {"Address", ipv4Config.address},
-                                     {"Gateway", ethData.default_gateway}});
-                if (ipv4Config.origin == "Static")
-                {
-                    ipv4StaticArray.push_back(
-                        {{"AddressOrigin", ipv4Config.origin},
-                         {"SubnetMask", ipv4Config.netmask},
-                         {"Address", ipv4Config.address},
-                         {"Gateway", ethData.default_gateway}});
-                }
+            ipv4Array.push_back({{"AddressOrigin", ipv4Config.origin},
+                                 {"SubnetMask", ipv4Config.netmask},
+                                 {"Address", ipv4Config.address},
+                                 {"Gateway", ethData.default_gateway}});
+            if (ipv4Config.origin == "Static")
+            {
+                ipv4StaticArray.push_back(
+                    {{"AddressOrigin", ipv4Config.origin},
+                     {"SubnetMask", ipv4Config.netmask},
+                     {"Address", ipv4Config.address},
+                     {"Gateway", ethData.default_gateway}});
             }
         }
     }
+}
 
-    void handleHypervisorIPv4StaticPatch(
-        const std::string& ifaceId, const nlohmann::json& input,
-        const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+inline void setDHCPEnabled(const std::string& ifaceId,
+                           const bool& ipv4DHCPEnabled,
+                           const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+{
+    const std::string dhcp = getDhcpEnabledEnumeration(ipv4DHCPEnabled, false);
+    crow::connections::systemBus->async_method_call(
+        [asyncResp](const boost::system::error_code ec) {
+            if (ec)
+            {
+                BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
+                messages::internalError(asyncResp->res);
+                return;
+            }
+        },
+        "xyz.openbmc_project.Settings",
+        "/xyz/openbmc_project/network/hypervisor/" + ifaceId,
+        "org.freedesktop.DBus.Properties", "Set",
+        "xyz.openbmc_project.Network.EthernetInterface", "DHCPEnabled",
+        std::variant<std::string>{dhcp});
+
+    // Set the IPv4 address origin to the DHCP / Static as per the new value
+    // of the DHCPEnabled property
+    std::string origin;
+    if (ipv4DHCPEnabled == false)
     {
-        if ((!input.is_array()) || input.empty())
+        origin = "xyz.openbmc_project.Network.IP.AddressOrigin.Static";
+    }
+    else
+    {
+        // DHCPEnabled is set to true. Delete the current IPv4 settings
+        // to receive the new values from DHCP server.
+        deleteHypervisorIPv4(ifaceId, asyncResp);
+        origin = "xyz.openbmc_project.Network.IP.AddressOrigin.DHCP";
+    }
+    crow::connections::systemBus->async_method_call(
+        [asyncResp](const boost::system::error_code ec) {
+            if (ec)
+            {
+                BMCWEB_LOG_ERROR << "DBUS response error " << ec;
+                messages::internalError(asyncResp->res);
+                return;
+            }
+            BMCWEB_LOG_DEBUG << "Hypervisor IPaddress Origin is Set";
+        },
+        "xyz.openbmc_project.Settings",
+        "/xyz/openbmc_project/network/hypervisor/" + ifaceId + "/ipv4/addr0",
+        "org.freedesktop.DBus.Properties", "Set",
+        "xyz.openbmc_project.Network.IP", "Origin",
+        std::variant<std::string>(origin));
+}
+
+inline void handleHypervisorIPv4StaticPatch(
+    const std::string& ifaceId, const nlohmann::json& input,
+    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+{
+    if ((!input.is_array()) || input.empty())
+    {
+        messages::propertyValueTypeError(asyncResp->res, input.dump(),
+                                         "IPv4StaticAddresses");
+        return;
+    }
+
+    // Hypervisor considers the first IP address in the array list
+    // as the Hypervisor's virtual management interface supports single IPv4
+    // address
+    const nlohmann::json& thisJson = input[0];
+
+    // For the error string
+    std::string pathString = "IPv4StaticAddresses/1";
+
+    if (!thisJson.is_null() && !thisJson.empty())
+    {
+        std::optional<std::string> address;
+        std::optional<std::string> subnetMask;
+        std::optional<std::string> gateway;
+        nlohmann::json thisJsonCopy = thisJson;
+        if (!json_util::readJson(thisJsonCopy, asyncResp->res, "Address",
+                                 address, "SubnetMask", subnetMask, "Gateway",
+                                 gateway))
         {
-            messages::propertyValueTypeError(asyncResp->res, input.dump(),
-                                             "IPv4StaticAddresses");
+            messages::propertyValueFormatError(
+                asyncResp->res,
+                thisJson.dump(2, ' ', true,
+                              nlohmann::json::error_handler_t::replace),
+                pathString);
             return;
         }
 
-        // Hypervisor considers the first IP address in the array list
-        // as the Hypervisor's virtual management interface supports single IPv4
-        // address
-        const nlohmann::json& thisJson = input[0];
-
-        // For the error string
-        std::string pathString = "IPv4StaticAddresses/1";
-
-        if (!thisJson.is_null() && !thisJson.empty())
+        uint8_t prefixLength = 0;
+        bool errorInEntry = false;
+        if (address)
         {
-            std::optional<std::string> address;
-            std::optional<std::string> subnetMask;
-            std::optional<std::string> gateway;
-            nlohmann::json thisJsonCopy = thisJson;
-            if (!json_util::readJson(thisJsonCopy, asyncResp->res, "Address",
-                                     address, "SubnetMask", subnetMask,
-                                     "Gateway", gateway))
+            if (!ipv4VerifyIpAndGetBitcount(*address))
             {
-                messages::propertyValueFormatError(
-                    asyncResp->res,
-                    thisJson.dump(2, ' ', true,
-                                  nlohmann::json::error_handler_t::replace),
-                    pathString);
-                return;
-            }
-
-            uint8_t prefixLength = 0;
-            bool errorInEntry = false;
-            if (address)
-            {
-                if (!ipv4VerifyIpAndGetBitcount(*address))
-                {
-                    messages::propertyValueFormatError(asyncResp->res, *address,
-                                                       pathString + "/Address");
-                    errorInEntry = true;
-                }
-            }
-            else
-            {
-                messages::propertyMissing(asyncResp->res,
-                                          pathString + "/Address");
+                messages::propertyValueFormatError(asyncResp->res, *address,
+                                                   pathString + "/Address");
                 errorInEntry = true;
             }
-
-            if (subnetMask)
-            {
-                if (!ipv4VerifyIpAndGetBitcount(*subnetMask, &prefixLength))
-                {
-                    messages::propertyValueFormatError(
-                        asyncResp->res, *subnetMask,
-                        pathString + "/SubnetMask");
-                    errorInEntry = true;
-                }
-            }
-            else
-            {
-                messages::propertyMissing(asyncResp->res,
-                                          pathString + "/SubnetMask");
-                errorInEntry = true;
-            }
-
-            if (gateway)
-            {
-                if (!ipv4VerifyIpAndGetBitcount(*gateway))
-                {
-                    messages::propertyValueFormatError(asyncResp->res, *gateway,
-                                                       pathString + "/Gateway");
-                    errorInEntry = true;
-                }
-            }
-            else
-            {
-                messages::propertyMissing(asyncResp->res,
-                                          pathString + "/Gateway");
-                errorInEntry = true;
-            }
-
-            if (errorInEntry)
-            {
-                return;
-            }
-
-            BMCWEB_LOG_DEBUG << "Calling createHypervisorIPv4 on : " << ifaceId
-                             << "," << *address;
-            createHypervisorIPv4(ifaceId, prefixLength, *gateway, *address,
-                                 asyncResp);
-            // Set the DHCPEnabled to false since the Static IPv4 is set
-            setDHCPEnabled(ifaceId, false, asyncResp);
         }
         else
         {
-            if (thisJson.is_null())
+            messages::propertyMissing(asyncResp->res, pathString + "/Address");
+            errorInEntry = true;
+        }
+
+        if (subnetMask)
+        {
+            if (!ipv4VerifyIpAndGetBitcount(*subnetMask, &prefixLength))
             {
-                deleteHypervisorIPv4(ifaceId, asyncResp);
+                messages::propertyValueFormatError(asyncResp->res, *subnetMask,
+                                                   pathString + "/SubnetMask");
+                errorInEntry = true;
             }
         }
-    }
-
-    bool isHostnameValid(const std::string& hostName)
-    {
-        // As per RFC 1123
-        // Allow up to 255 characters
-        if (hostName.length() > 255)
+        else
         {
-            return false;
+            messages::propertyMissing(asyncResp->res,
+                                      pathString + "/SubnetMask");
+            errorInEntry = true;
         }
-        // Validate the regex
-        const std::regex pattern(
-            "^[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9]$");
 
-        return std::regex_match(hostName, pattern);
-    }
-
-    void
-        handleHostnamePatch(const std::string& hostName,
-                            const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
-    {
-        if (!isHostnameValid(hostName))
+        if (gateway)
         {
-            messages::propertyValueFormatError(asyncResp->res, hostName,
-                                               "HostName");
+            if (!ipv4VerifyIpAndGetBitcount(*gateway))
+            {
+                messages::propertyValueFormatError(asyncResp->res, *gateway,
+                                                   pathString + "/Gateway");
+                errorInEntry = true;
+            }
+        }
+        else
+        {
+            messages::propertyMissing(asyncResp->res, pathString + "/Gateway");
+            errorInEntry = true;
+        }
+
+        if (errorInEntry)
+        {
             return;
         }
 
-        asyncResp->res.jsonValue["HostName"] = hostName;
-        crow::connections::systemBus->async_method_call(
-            [asyncResp](const boost::system::error_code ec) {
-                if (ec)
-                {
-                    messages::internalError(asyncResp->res);
-                }
-            },
-            "xyz.openbmc_project.Settings",
-            "/xyz/openbmc_project/network/hypervisor",
-            "org.freedesktop.DBus.Properties", "Set",
-            "xyz.openbmc_project.Network.SystemConfiguration", "HostName",
-            std::variant<std::string>(hostName));
+        BMCWEB_LOG_DEBUG << "Calling createHypervisorIPv4 on : " << ifaceId
+                         << "," << *address;
+        createHypervisorIPv4(ifaceId, prefixLength, *gateway, *address,
+                             asyncResp);
+        // Set the DHCPEnabled to false since the Static IPv4 is set
+        setDHCPEnabled(ifaceId, false, asyncResp);
     }
-
-    void setIPv4InterfaceEnabled(
-        const std::string& ifaceId, const bool& isActive,
-        const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+    else
     {
-        crow::connections::systemBus->async_method_call(
-            [asyncResp](const boost::system::error_code ec) {
-                if (ec)
-                {
-                    BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
-                    messages::internalError(asyncResp->res);
-                    return;
-                }
-            },
-            "xyz.openbmc_project.Settings",
-            "/xyz/openbmc_project/network/hypervisor/" + ifaceId +
-                "/ipv4/addr0",
-            "org.freedesktop.DBus.Properties", "Set",
-            "xyz.openbmc_project.Object.Enable", "Enabled",
-            std::variant<bool>(isActive));
-    }
-
-    void setDHCPEnabled(const std::string& ifaceId, const bool& ipv4DHCPEnabled,
-                        const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
-    {
-        const std::string dhcp =
-            getDhcpEnabledEnumeration(ipv4DHCPEnabled, false);
-        crow::connections::systemBus->async_method_call(
-            [asyncResp](const boost::system::error_code ec) {
-                if (ec)
-                {
-                    BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
-                    messages::internalError(asyncResp->res);
-                    return;
-                }
-            },
-            "xyz.openbmc_project.Settings",
-            "/xyz/openbmc_project/network/hypervisor/" + ifaceId,
-            "org.freedesktop.DBus.Properties", "Set",
-            "xyz.openbmc_project.Network.EthernetInterface", "DHCPEnabled",
-            std::variant<std::string>{dhcp});
-
-        // Set the IPv4 address origin to the DHCP / Static as per the new value
-        // of the DHCPEnabled property
-        std::string origin;
-        if (ipv4DHCPEnabled == false)
+        if (thisJson.is_null())
         {
-            origin = "xyz.openbmc_project.Network.IP.AddressOrigin.Static";
-        }
-        else
-        {
-            // DHCPEnabled is set to true. Delete the current IPv4 settings
-            // to receive the new values from DHCP server.
             deleteHypervisorIPv4(ifaceId, asyncResp);
-            origin = "xyz.openbmc_project.Network.IP.AddressOrigin.DHCP";
         }
-        crow::connections::systemBus->async_method_call(
-            [asyncResp](const boost::system::error_code ec) {
-                if (ec)
-                {
-                    BMCWEB_LOG_ERROR << "DBUS response error " << ec;
-                    messages::internalError(asyncResp->res);
-                    return;
-                }
-                BMCWEB_LOG_DEBUG << "Hypervisor IPaddress Origin is Set";
-            },
-            "xyz.openbmc_project.Settings",
-            "/xyz/openbmc_project/network/hypervisor/" + ifaceId +
-                "/ipv4/addr0",
-            "org.freedesktop.DBus.Properties", "Set",
-            "xyz.openbmc_project.Network.IP", "Origin",
-            std::variant<std::string>(origin));
     }
+}
+
+inline bool isHostnameValid(const std::string& hostName)
+{
+    // As per RFC 1123
+    // Allow up to 255 characters
+    if (hostName.length() > 255)
+    {
+        return false;
+    }
+    // Validate the regex
+    const std::regex pattern(
+        "^[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9]$");
+
+    return std::regex_match(hostName, pattern);
+}
+
+inline void
+    handleHostnamePatch(const std::string& hostName,
+                        const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+{
+    if (!isHostnameValid(hostName))
+    {
+        messages::propertyValueFormatError(asyncResp->res, hostName,
+                                           "HostName");
+        return;
+    }
+
+    asyncResp->res.jsonValue["HostName"] = hostName;
+    crow::connections::systemBus->async_method_call(
+        [asyncResp](const boost::system::error_code ec) {
+            if (ec)
+            {
+                messages::internalError(asyncResp->res);
+            }
+        },
+        "xyz.openbmc_project.Settings",
+        "/xyz/openbmc_project/network/hypervisor",
+        "org.freedesktop.DBus.Properties", "Set",
+        "xyz.openbmc_project.Network.SystemConfiguration", "HostName",
+        std::variant<std::string>(hostName));
+}
+
+inline void
+    setIPv4InterfaceEnabled(const std::string& ifaceId, const bool& isActive,
+                            const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+{
+    crow::connections::systemBus->async_method_call(
+        [asyncResp](const boost::system::error_code ec) {
+            if (ec)
+            {
+                BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
+                messages::internalError(asyncResp->res);
+                return;
+            }
+        },
+        "xyz.openbmc_project.Settings",
+        "/xyz/openbmc_project/network/hypervisor/" + ifaceId + "/ipv4/addr0",
+        "org.freedesktop.DBus.Properties", "Set",
+        "xyz.openbmc_project.Object.Enable", "Enabled",
+        std::variant<bool>(isActive));
+}
+
+inline void requestRoutesHypervisorSystems(App& app)
+{
+    /**
+     * Hypervisor Systems derived class for delivering Computer Systems Schema.
+     */
+
+    BMCWEB_ROUTE(app, "/redfish/v1/Systems/hypervisor/")
+        .privileges({"Login"})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                crow::connections::systemBus->async_method_call(
+                    [asyncResp](const boost::system::error_code ec,
+                                const std::variant<std::string>& /*hostName*/) {
+                        if (ec)
+                        {
+                            messages::resourceNotFound(asyncResp->res, "System",
+                                                       "hypervisor");
+                            return;
+                        }
+                        BMCWEB_LOG_DEBUG << "Hypervisor is available";
+
+                        asyncResp->res.jsonValue["@odata.type"] =
+                            "#ComputerSystem.v1_6_0.ComputerSystem";
+                        asyncResp->res.jsonValue["@odata.id"] =
+                            "/redfish/v1/Systems/hypervisor";
+                        asyncResp->res.jsonValue["Description"] = "Hypervisor";
+                        asyncResp->res.jsonValue["Name"] = "Hypervisor";
+                        asyncResp->res.jsonValue["Id"] = "hypervisor";
+                        asyncResp->res.jsonValue["Links"]["ManagedBy"] = {
+                            {{"@odata.id", "/redfish/v1/Managers/bmc"}}};
+                        asyncResp->res.jsonValue["EthernetInterfaces"] = {
+                            {"@odata.id", "/redfish/v1/Systems/hypervisor/"
+                                          "EthernetInterfaces"}};
+                        getHypervisorState(asyncResp);
+                        getHypervisorActions(asyncResp);
+                        // TODO: Add "SystemType" : "hypervisor"
+                    },
+                    "xyz.openbmc_project.Settings",
+                    "/xyz/openbmc_project/network/hypervisor",
+                    "org.freedesktop.DBus.Properties", "Get",
+                    "xyz.openbmc_project.Network.SystemConfiguration",
+                    "HostName");
+            });
 
     /**
-     * Functions triggers appropriate requests on DBus
+     * HypervisorInterfaceCollection class to handle the GET and PATCH on
+     * Hypervisor Interface
      */
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&,
-               const std::vector<std::string>& params) override
-    {
-        if (params.size() != 1)
-        {
-            messages::internalError(asyncResp->res);
-            return;
-        }
 
-        getHypervisorIfaceData(
-            params[0],
-            [this, asyncResp, ifaceId{std::string(params[0])}](
-                const bool& success, const EthernetInterfaceData& ethData,
-                const boost::container::flat_set<IPv4AddressData>& ipv4Data) {
-                if (!success)
-                {
-                    messages::resourceNotFound(asyncResp->res,
-                                               "EthernetInterface", ifaceId);
-                    return;
-                }
-                asyncResp->res.jsonValue["@odata.type"] =
-                    "#EthernetInterface.v1_5_1.EthernetInterface";
-                asyncResp->res.jsonValue["Name"] =
-                    "Hypervisor Ethernet Interface";
-                asyncResp->res.jsonValue["Description"] =
-                    "Hypervisor's Virtual Management Ethernet Interface";
-                parseInterfaceData(asyncResp->res.jsonValue, ifaceId, ethData,
-                                   ipv4Data);
+    BMCWEB_ROUTE(app, "/redfish/v1/Systems/hypervisor/EthernetInterfaces/")
+        .privileges({"Login"})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                const std::array<const char*, 1> interfaces = {
+                    "xyz.openbmc_project.Network.EthernetInterface"};
+
+                crow::connections::systemBus->async_method_call(
+                    [asyncResp](const boost::system::error_code error,
+                                const std::vector<std::string>& ifaceList) {
+                        if (error)
+                        {
+                            messages::resourceNotFound(asyncResp->res, "System",
+                                                       "hypervisor");
+                            return;
+                        }
+                        asyncResp->res.jsonValue["@odata.type"] =
+                            "#EthernetInterfaceCollection."
+                            "EthernetInterfaceCollection";
+                        asyncResp->res.jsonValue["@odata.id"] =
+                            "/redfish/v1/Systems/hypervisor/EthernetInterfaces";
+                        asyncResp->res.jsonValue["Name"] =
+                            "Hypervisor Ethernet "
+                            "Interface Collection";
+                        asyncResp->res.jsonValue["Description"] =
+                            "Collection of Virtual Management "
+                            "Interfaces for the hypervisor";
+
+                        nlohmann::json& ifaceArray =
+                            asyncResp->res.jsonValue["Members"];
+                        ifaceArray = nlohmann::json::array();
+                        for (const std::string& iface : ifaceList)
+                        {
+                            sdbusplus::message::object_path path(iface);
+                            std::string name = path.filename();
+                            if (name.empty())
+                            {
+                                continue;
+                            }
+
+                            ifaceArray.push_back(
+                                {{"@odata.id", "/redfish/v1/Systems/hypervisor/"
+                                               "EthernetInterfaces/" +
+                                                   name}});
+                        }
+                        asyncResp->res.jsonValue["Members@odata.count"] =
+                            ifaceArray.size();
+                    },
+                    "xyz.openbmc_project.ObjectMapper",
+                    "/xyz/openbmc_project/object_mapper",
+                    "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths",
+                    "/xyz/openbmc_project/network/hypervisor", 0, interfaces);
             });
-    }
 
-    void doPatch(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                 const crow::Request& req,
-                 const std::vector<std::string>& params) override
-    {
+    BMCWEB_ROUTE(app,
+                 "/redfish/v1/Systems/hypervisor/EthernetInterfaces/<str>/")
+        .privileges({"Login"})
+        .methods(
+            boost::beast::http::verb::get)([](const crow::Request&,
+                                              const std::shared_ptr<
+                                                  bmcweb::AsyncResp>& asyncResp,
+                                              const std::string& id) {
+            getHypervisorIfaceData(
+                id,
+                [asyncResp, ifaceId{std::string(id)}](
+                    const bool& success, const EthernetInterfaceData& ethData,
+                    const boost::container::flat_set<IPv4AddressData>&
+                        ipv4Data) {
+                    if (!success)
+                    {
+                        messages::resourceNotFound(
+                            asyncResp->res, "EthernetInterface", ifaceId);
+                        return;
+                    }
+                    asyncResp->res.jsonValue["@odata.type"] =
+                        "#EthernetInterface.v1_5_1.EthernetInterface";
+                    asyncResp->res.jsonValue["Name"] =
+                        "Hypervisor Ethernet Interface";
+                    asyncResp->res.jsonValue["Description"] =
+                        "Hypervisor's Virtual Management Ethernet Interface";
+                    parseInterfaceData(asyncResp->res.jsonValue, ifaceId,
+                                       ethData, ipv4Data);
+                });
+        });
 
-        if (params.size() != 1)
-        {
-            messages::internalError(asyncResp->res);
-            return;
-        }
+    BMCWEB_ROUTE(app,
+                 "/redfish/v1/Systems/hypervisor/EthernetInterfaces/<str>/")
+        .privileges({"ConfigureComponents"})
+        .methods(
+            boost::beast::http::verb::
+                patch)([](const crow::Request& req,
+                          const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+                          const std::string& ifaceId) {
+            std::optional<std::string> hostName;
+            std::optional<std::vector<nlohmann::json>> ipv4StaticAddresses;
+            std::optional<nlohmann::json> ipv4Addresses;
+            std::optional<nlohmann::json> dhcpv4;
+            std::optional<bool> ipv4DHCPEnabled;
 
-        const std::string& ifaceId = params[0];
-        std::optional<std::string> hostName;
-        std::optional<std::vector<nlohmann::json>> ipv4StaticAddresses;
-        std::optional<nlohmann::json> ipv4Addresses;
-        std::optional<nlohmann::json> dhcpv4;
-        std::optional<bool> ipv4DHCPEnabled;
-
-        if (!json_util::readJson(req, asyncResp->res, "HostName", hostName,
-                                 "IPv4StaticAddresses", ipv4StaticAddresses,
-                                 "IPv4Addresses", ipv4Addresses, "DHCPv4",
-                                 dhcpv4))
-        {
-            return;
-        }
-
-        if (ipv4Addresses)
-        {
-            messages::propertyNotWritable(asyncResp->res, "IPv4Addresses");
-        }
-
-        if (dhcpv4)
-        {
-            if (!json_util::readJson(*dhcpv4, asyncResp->res, "DHCPEnabled",
-                                     ipv4DHCPEnabled))
+            if (!json_util::readJson(req, asyncResp->res, "HostName", hostName,
+                                     "IPv4StaticAddresses", ipv4StaticAddresses,
+                                     "IPv4Addresses", ipv4Addresses, "DHCPv4",
+                                     dhcpv4))
             {
                 return;
             }
-        }
 
-        getHypervisorIfaceData(
-            ifaceId,
-            [this, asyncResp, ifaceId, hostName = std::move(hostName),
-             ipv4StaticAddresses = std::move(ipv4StaticAddresses),
-             ipv4DHCPEnabled, dhcpv4 = std::move(dhcpv4)](
-                const bool& success, const EthernetInterfaceData& ethData,
-                const boost::container::flat_set<IPv4AddressData>&) {
-                if (!success)
+            if (ipv4Addresses)
+            {
+                messages::propertyNotWritable(asyncResp->res, "IPv4Addresses");
+            }
+
+            if (dhcpv4)
+            {
+                if (!json_util::readJson(*dhcpv4, asyncResp->res, "DHCPEnabled",
+                                         ipv4DHCPEnabled))
                 {
-                    messages::resourceNotFound(asyncResp->res,
-                                               "EthernetInterface", ifaceId);
                     return;
                 }
+            }
 
-                if (ipv4StaticAddresses)
-                {
-                    const nlohmann::json& ipv4Static = *ipv4StaticAddresses;
-                    if (ipv4Static.begin() == ipv4Static.end())
+            getHypervisorIfaceData(
+                ifaceId,
+                [asyncResp, ifaceId, hostName = std::move(hostName),
+                 ipv4StaticAddresses = std::move(ipv4StaticAddresses),
+                 ipv4DHCPEnabled, dhcpv4 = std::move(dhcpv4)](
+                    const bool& success, const EthernetInterfaceData& ethData,
+                    const boost::container::flat_set<IPv4AddressData>&) {
+                    if (!success)
                     {
-                        messages::propertyValueTypeError(
-                            asyncResp->res,
-                            ipv4Static.dump(
-                                2, ' ', true,
-                                nlohmann::json::error_handler_t::replace),
-                            "IPv4StaticAddresses");
+                        messages::resourceNotFound(
+                            asyncResp->res, "EthernetInterface", ifaceId);
                         return;
                     }
 
-                    // One and only one hypervisor instance supported
-                    if (ipv4Static.size() != 1)
+                    if (ipv4StaticAddresses)
                     {
-                        messages::propertyValueFormatError(
-                            asyncResp->res,
-                            ipv4Static.dump(
-                                2, ' ', true,
-                                nlohmann::json::error_handler_t::replace),
-                            "IPv4StaticAddresses");
-                        return;
+                        const nlohmann::json& ipv4Static = *ipv4StaticAddresses;
+                        if (ipv4Static.begin() == ipv4Static.end())
+                        {
+                            messages::propertyValueTypeError(
+                                asyncResp->res,
+                                ipv4Static.dump(
+                                    2, ' ', true,
+                                    nlohmann::json::error_handler_t::replace),
+                                "IPv4StaticAddresses");
+                            return;
+                        }
+
+                        // One and only one hypervisor instance supported
+                        if (ipv4Static.size() != 1)
+                        {
+                            messages::propertyValueFormatError(
+                                asyncResp->res,
+                                ipv4Static.dump(
+                                    2, ' ', true,
+                                    nlohmann::json::error_handler_t::replace),
+                                "IPv4StaticAddresses");
+                            return;
+                        }
+
+                        const nlohmann::json& ipv4Json = ipv4Static[0];
+                        // Check if the param is 'null'. If its null, it means
+                        // that user wants to delete the IP address. Deleting
+                        // the IP address is allowed only if its statically
+                        // configured. Deleting the address originated from DHCP
+                        // is not allowed.
+                        if ((ipv4Json.is_null()) &&
+                            (translateDHCPEnabledToBool(ethData.DHCPEnabled,
+                                                        true)))
+                        {
+                            BMCWEB_LOG_INFO
+                                << "Ignoring the delete on ipv4StaticAddresses "
+                                   "as the interface is DHCP enabled";
+                        }
+                        else
+                        {
+                            handleHypervisorIPv4StaticPatch(ifaceId, ipv4Static,
+                                                            asyncResp);
+                        }
                     }
 
-                    const nlohmann::json& ipv4Json = ipv4Static[0];
-                    // Check if the param is 'null'. If its null, it means that
-                    // user wants to delete the IP address. Deleting the IP
-                    // address is allowed only if its statically configured.
-                    // Deleting the address originated from DHCP is not allowed.
-                    if ((ipv4Json.is_null()) &&
-                        (translateDHCPEnabledToBool(ethData.DHCPEnabled, true)))
+                    if (hostName)
                     {
-                        BMCWEB_LOG_INFO
-                            << "Ignoring the delete on ipv4StaticAddresses "
-                               "as the interface is DHCP enabled";
+                        handleHostnamePatch(*hostName, asyncResp);
                     }
-                    else
+
+                    if (dhcpv4)
                     {
-                        handleHypervisorIPv4StaticPatch(ifaceId, ipv4Static,
-                                                        asyncResp);
+                        setDHCPEnabled(ifaceId, *ipv4DHCPEnabled, asyncResp);
                     }
-                }
 
-                if (hostName)
-                {
-                    handleHostnamePatch(*hostName, asyncResp);
-                }
+                    // Set this interface to disabled/inactive. This will be set
+                    // to enabled/active by the pldm once the hypervisor
+                    // consumes the updated settings from the user.
+                    setIPv4InterfaceEnabled(ifaceId, false, asyncResp);
+                });
+            asyncResp->res.result(boost::beast::http::status::accepted);
+        });
 
-                if (dhcpv4)
-                {
-                    setDHCPEnabled(ifaceId, *ipv4DHCPEnabled, asyncResp);
-                }
-
-                // Set this interface to disabled/inactive. This will be set to
-                // enabled/active by the pldm once the hypervisor consumes the
-                // updated settings from the user.
-                setIPv4InterfaceEnabled(ifaceId, false, asyncResp);
-            });
-        asyncResp->res.result(boost::beast::http::status::accepted);
-    }
-};
-
-/**
- * HypervisorResetActionInfo derived class for delivering Computer Systems
- * ResetType AllowableValues using ResetInfo schema.
- */
-class HypervisorResetActionInfo : public Node
-{
-  public:
-    /*
-     * Default Constructor
-     */
-    HypervisorResetActionInfo(App& app) :
-        Node(app, "/redfish/v1/Systems/hypervisor/ResetActionInfo/")
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
-    }
-
-  private:
-    /**
-     * Functions triggers appropriate requests on DBus
-     */
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&, const std::vector<std::string>&) override
-    {
-        // Only return action info if hypervisor D-Bus object present
-        crow::connections::systemBus->async_method_call(
-            [asyncResp](const boost::system::error_code ec,
+    BMCWEB_ROUTE(app, "/redfish/v1/Systems/hypervisor/ResetActionInfo/")
+        .privileges({"Login"})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                // Only return action info if hypervisor D-Bus object present
+                crow::connections::systemBus->async_method_call(
+                    [asyncResp](
+                        const boost::system::error_code ec,
                         const std::vector<std::pair<
                             std::string, std::vector<std::string>>>& objInfo) {
-                if (ec)
+                        if (ec)
+                        {
+                            BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
+
+                            // No hypervisor objects found by mapper
+                            if (ec.value() == boost::system::errc::io_error)
+                            {
+                                messages::resourceNotFound(asyncResp->res,
+                                                           "hypervisor",
+                                                           "ResetActionInfo");
+                                return;
+                            }
+
+                            messages::internalError(asyncResp->res);
+                            return;
+                        }
+
+                        // One and only one hypervisor instance supported
+                        if (objInfo.size() != 1)
+                        {
+                            messages::internalError(asyncResp->res);
+                            return;
+                        }
+
+                        // The hypervisor object only support the ability to
+                        // turn On The system object Action should be utilized
+                        // for other operations
+                        asyncResp->res.jsonValue = {
+                            {"@odata.type", "#ActionInfo.v1_1_2.ActionInfo"},
+                            {"@odata.id",
+                             "/redfish/v1/Systems/hypervisor/ResetActionInfo"},
+                            {"Name", "Reset Action Info"},
+                            {"Id", "ResetActionInfo"},
+                            {"Parameters",
+                             {{{"Name", "ResetType"},
+                               {"Required", true},
+                               {"DataType", "String"},
+                               {"AllowableValues", {"On"}}}}}};
+                    },
+                    "xyz.openbmc_project.ObjectMapper",
+                    "/xyz/openbmc_project/object_mapper",
+                    "xyz.openbmc_project.ObjectMapper", "GetObject",
+                    "/xyz/openbmc_project/state/hypervisor0",
+                    std::array<const char*, 1>{
+                        "xyz.openbmc_project.State.Host"});
+            });
+
+    BMCWEB_ROUTE(app,
+                 "/redfish/v1/Systems/hypervisor/Actions/ComputerSystem.Reset/")
+        .privileges({"ConfigureComponents"})
+        .methods(boost::beast::http::verb::post)(
+            [](const crow::Request& req,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                std::optional<std::string> resetType;
+                if (!json_util::readJson(req, asyncResp->res, "ResetType",
+                                         resetType))
                 {
-                    BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
-
-                    // No hypervisor objects found by mapper
-                    if (ec.value() == boost::system::errc::io_error)
-                    {
-                        messages::resourceNotFound(asyncResp->res, "hypervisor",
-                                                   "ResetActionInfo");
-                        return;
-                    }
-
-                    messages::internalError(asyncResp->res);
+                    // readJson adds appropriate error to response
                     return;
                 }
 
-                // One and only one hypervisor instance supported
-                if (objInfo.size() != 1)
+                if (!resetType)
                 {
-                    messages::internalError(asyncResp->res);
+                    messages::actionParameterMissing(
+                        asyncResp->res, "ComputerSystem.Reset", "ResetType");
                     return;
                 }
 
-                // The hypervisor object only support the ability to turn On
-                // The system object Action should be utilized for other
-                // operations
-                asyncResp->res.jsonValue = {
-                    {"@odata.type", "#ActionInfo.v1_1_2.ActionInfo"},
-                    {"@odata.id",
-                     "/redfish/v1/Systems/hypervisor/ResetActionInfo"},
-                    {"Name", "Reset Action Info"},
-                    {"Id", "ResetActionInfo"},
-                    {"Parameters",
-                     {{{"Name", "ResetType"},
-                       {"Required", true},
-                       {"DataType", "String"},
-                       {"AllowableValues", {"On"}}}}}};
-            },
-            "xyz.openbmc_project.ObjectMapper",
-            "/xyz/openbmc_project/object_mapper",
-            "xyz.openbmc_project.ObjectMapper", "GetObject",
-            "/xyz/openbmc_project/state/hypervisor0",
-            std::array<const char*, 1>{"xyz.openbmc_project.State.Host"});
-    }
-};
-
-/**
- * HypervisorActionsReset class supports the POST method for Reset action.
- * The class sends data directly to D-Bus.
- */
-class HypervisorActionsReset : public Node
-{
-  public:
-    HypervisorActionsReset(App& app) :
-        Node(app,
-             "/redfish/v1/Systems/hypervisor/Actions/ComputerSystem.Reset/")
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
-    }
-
-  private:
-    /**
-     * Function handles POST method request.
-     * Analyzes POST body message before sends Reset request data to D-Bus.
-     */
-    void doPost(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                const crow::Request& req,
-                const std::vector<std::string>&) override
-    {
-
-        std::optional<std::string> resetType;
-        if (!json_util::readJson(req, asyncResp->res, "ResetType", resetType))
-        {
-            // readJson adds appropriate error to response
-            return;
-        }
-
-        if (!resetType)
-        {
-            messages::actionParameterMissing(
-                asyncResp->res, "ComputerSystem.Reset", "ResetType");
-            return;
-        }
-
-        // Hypervisor object only support On operation
-        if (resetType != "On")
-        {
-            messages::propertyValueNotInList(asyncResp->res, *resetType,
-                                             "ResetType");
-            return;
-        }
-
-        std::string command = "xyz.openbmc_project.State.Host.Transition.On";
-
-        crow::connections::systemBus->async_method_call(
-            [asyncResp, resetType](const boost::system::error_code ec) {
-                if (ec)
+                // Hypervisor object only support On operation
+                if (resetType != "On")
                 {
-                    BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
-                    if (ec.value() == boost::asio::error::invalid_argument)
-                    {
-                        messages::actionParameterNotSupported(
-                            asyncResp->res, *resetType, "Reset");
-                        return;
-                    }
-
-                    if (ec.value() == boost::asio::error::host_unreachable)
-                    {
-                        messages::resourceNotFound(asyncResp->res, "Actions",
-                                                   "Reset");
-                        return;
-                    }
-
-                    messages::internalError(asyncResp->res);
+                    messages::propertyValueNotInList(asyncResp->res, *resetType,
+                                                     "ResetType");
                     return;
                 }
-                messages::success(asyncResp->res);
-            },
-            "xyz.openbmc_project.State.Hypervisor",
-            "/xyz/openbmc_project/state/hypervisor0",
-            "org.freedesktop.DBus.Properties", "Set",
-            "xyz.openbmc_project.State.Host", "RequestedHostTransition",
-            std::variant<std::string>{std::move(command)});
-    }
-};
+
+                std::string command =
+                    "xyz.openbmc_project.State.Host.Transition.On";
+
+                crow::connections::systemBus->async_method_call(
+                    [asyncResp, resetType](const boost::system::error_code ec) {
+                        if (ec)
+                        {
+                            BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
+                            if (ec.value() ==
+                                boost::asio::error::invalid_argument)
+                            {
+                                messages::actionParameterNotSupported(
+                                    asyncResp->res, *resetType, "Reset");
+                                return;
+                            }
+
+                            if (ec.value() ==
+                                boost::asio::error::host_unreachable)
+                            {
+                                messages::resourceNotFound(asyncResp->res,
+                                                           "Actions", "Reset");
+                                return;
+                            }
+
+                            messages::internalError(asyncResp->res);
+                            return;
+                        }
+                        messages::success(asyncResp->res);
+                    },
+                    "xyz.openbmc_project.State.Hypervisor",
+                    "/xyz/openbmc_project/state/hypervisor0",
+                    "org.freedesktop.DBus.Properties", "Set",
+                    "xyz.openbmc_project.State.Host", "RequestedHostTransition",
+                    std::variant<std::string>{std::move(command)});
+            });
+}
 } // namespace redfish
diff --git a/redfish-core/lib/led.hpp b/redfish-core/lib/led.hpp
index fe1842f..1fdf5e7 100644
--- a/redfish-core/lib/led.hpp
+++ b/redfish-core/lib/led.hpp
@@ -19,6 +19,8 @@
 #include "dbus_utility.hpp"
 #include "redfish_util.hpp"
 
+#include <app.hpp>
+
 #include <variant>
 
 namespace redfish
diff --git a/redfish-core/lib/log_services.hpp b/redfish-core/lib/log_services.hpp
index efed764..b04d0f9 100644
--- a/redfish-core/lib/log_services.hpp
+++ b/redfish-core/lib/log_services.hpp
@@ -15,7 +15,6 @@
 */
 #pragma once
 
-#include "node.hpp"
 #include "registries.hpp"
 #include "registries/base_message_registry.hpp"
 #include "registries/openbmc_message_registry.hpp"
@@ -24,6 +23,7 @@
 #include <systemd/sd-journal.h>
 #include <unistd.h>
 
+#include <app.hpp>
 #include <boost/algorithm/string/replace.hpp>
 #include <boost/algorithm/string/split.hpp>
 #include <boost/beast/core/span.hpp>
@@ -129,9 +129,9 @@
     return "";
 }
 
-static int getJournalMetadata(sd_journal* journal,
-                              const std::string_view& field,
-                              std::string_view& contents)
+inline static int getJournalMetadata(sd_journal* journal,
+                                     const std::string_view& field,
+                                     std::string_view& contents)
 {
     const char* data = nullptr;
     size_t length = 0;
@@ -149,9 +149,9 @@
     return ret;
 }
 
-static int getJournalMetadata(sd_journal* journal,
-                              const std::string_view& field, const int& base,
-                              long int& contents)
+inline static int getJournalMetadata(sd_journal* journal,
+                                     const std::string_view& field,
+                                     const int& base, long int& contents)
 {
     int ret = 0;
     std::string_view metadata;
@@ -165,7 +165,8 @@
     return ret;
 }
 
-static bool getEntryTimestamp(sd_journal* journal, std::string& entryTimestamp)
+inline static bool getEntryTimestamp(sd_journal* journal,
+                                     std::string& entryTimestamp)
 {
     int ret = 0;
     uint64_t timestamp = 0;
@@ -231,8 +232,8 @@
     return true;
 }
 
-static bool getUniqueEntryID(sd_journal* journal, std::string& entryID,
-                             const bool firstEntry = true)
+inline static bool getUniqueEntryID(sd_journal* journal, std::string& entryID,
+                                    const bool firstEntry = true)
 {
     int ret = 0;
     static uint64_t prevTs = 0;
@@ -311,7 +312,7 @@
     return true;
 }
 
-static bool
+inline static bool
     getTimestampFromID(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                        const std::string& entryID, uint64_t& timestamp,
                        uint64_t& index)
@@ -864,7 +865,7 @@
                                    dumpType});
 }
 
-static void parseCrashdumpParameters(
+inline static void parseCrashdumpParameters(
     const std::vector<std::pair<std::string, VariantType>>& params,
     std::string& filename, std::string& timestamp, std::string& logfile)
 {
@@ -901,171 +902,144 @@
 }
 
 constexpr char const* postCodeIface = "xyz.openbmc_project.State.Boot.PostCode";
-class SystemLogServiceCollection : public Node
+inline void requestRoutesSystemLogServiceCollection(App& app)
 {
-  public:
-    SystemLogServiceCollection(App& app) :
-        Node(app, "/redfish/v1/Systems/system/LogServices/")
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-    }
-
-  private:
     /**
      * Functions triggers appropriate requests on DBus
      */
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&, const std::vector<std::string>&) override
-    {
-        // Collections don't include the static data added by SubRoute because
-        // it has a duplicate entry for members
-        asyncResp->res.jsonValue["@odata.type"] =
-            "#LogServiceCollection.LogServiceCollection";
-        asyncResp->res.jsonValue["@odata.id"] =
-            "/redfish/v1/Systems/system/LogServices";
-        asyncResp->res.jsonValue["Name"] = "System Log Services Collection";
-        asyncResp->res.jsonValue["Description"] =
-            "Collection of LogServices for this Computer System";
-        nlohmann::json& logServiceArray = asyncResp->res.jsonValue["Members"];
-        logServiceArray = nlohmann::json::array();
-        logServiceArray.push_back(
-            {{"@odata.id", "/redfish/v1/Systems/system/LogServices/EventLog"}});
+    BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/LogServices/")
+        .privileges({"Login"})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+
+            {
+                // Collections don't include the static data added by SubRoute
+                // because it has a duplicate entry for members
+                asyncResp->res.jsonValue["@odata.type"] =
+                    "#LogServiceCollection.LogServiceCollection";
+                asyncResp->res.jsonValue["@odata.id"] =
+                    "/redfish/v1/Systems/system/LogServices";
+                asyncResp->res.jsonValue["Name"] =
+                    "System Log Services Collection";
+                asyncResp->res.jsonValue["Description"] =
+                    "Collection of LogServices for this Computer System";
+                nlohmann::json& logServiceArray =
+                    asyncResp->res.jsonValue["Members"];
+                logServiceArray = nlohmann::json::array();
+                logServiceArray.push_back(
+                    {{"@odata.id",
+                      "/redfish/v1/Systems/system/LogServices/EventLog"}});
 #ifdef BMCWEB_ENABLE_REDFISH_DUMP_LOG
-        logServiceArray.push_back(
-            {{"@odata.id", "/redfish/v1/Systems/system/LogServices/Dump"}});
+                logServiceArray.push_back(
+                    {{"@odata.id",
+                      "/redfish/v1/Systems/system/LogServices/Dump"}});
 #endif
 
 #ifdef BMCWEB_ENABLE_REDFISH_CPU_LOG
-        logServiceArray.push_back(
-            {{"@odata.id",
-              "/redfish/v1/Systems/system/LogServices/Crashdump"}});
+                logServiceArray.push_back(
+                    {{"@odata.id",
+                      "/redfish/v1/Systems/system/LogServices/Crashdump"}});
 #endif
-        asyncResp->res.jsonValue["Members@odata.count"] =
-            logServiceArray.size();
+                asyncResp->res.jsonValue["Members@odata.count"] =
+                    logServiceArray.size();
 
-        crow::connections::systemBus->async_method_call(
-            [asyncResp](const boost::system::error_code ec,
-                        const std::vector<std::string>& subtreePath) {
-                if (ec)
-                {
-                    BMCWEB_LOG_ERROR << ec;
-                    return;
-                }
+                crow::connections::systemBus->async_method_call(
+                    [asyncResp](const boost::system::error_code ec,
+                                const std::vector<std::string>& subtreePath) {
+                        if (ec)
+                        {
+                            BMCWEB_LOG_ERROR << ec;
+                            return;
+                        }
 
-                for (auto& pathStr : subtreePath)
+                        for (auto& pathStr : subtreePath)
+                        {
+                            if (pathStr.find("PostCode") != std::string::npos)
+                            {
+                                nlohmann::json& logServiceArrayLocal =
+                                    asyncResp->res.jsonValue["Members"];
+                                logServiceArrayLocal.push_back(
+                                    {{"@odata.id", "/redfish/v1/Systems/system/"
+                                                   "LogServices/PostCodes"}});
+                                asyncResp->res
+                                    .jsonValue["Members@odata.count"] =
+                                    logServiceArrayLocal.size();
+                                return;
+                            }
+                        }
+                    },
+                    "xyz.openbmc_project.ObjectMapper",
+                    "/xyz/openbmc_project/object_mapper",
+                    "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", "/",
+                    0, std::array<const char*, 1>{postCodeIface});
+            });
+}
+
+inline void requestRoutesEventLogService(App& app)
+{
+    BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/LogServices/EventLog/")
+        .privileges({"Login"})
+        .methods(
+            boost::beast::http::verb::
+                get)([](const crow::Request&,
+                        const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+            asyncResp->res.jsonValue["@odata.id"] =
+                "/redfish/v1/Systems/system/LogServices/EventLog";
+            asyncResp->res.jsonValue["@odata.type"] =
+                "#LogService.v1_1_0.LogService";
+            asyncResp->res.jsonValue["Name"] = "Event Log Service";
+            asyncResp->res.jsonValue["Description"] =
+                "System Event Log Service";
+            asyncResp->res.jsonValue["Id"] = "EventLog";
+            asyncResp->res.jsonValue["OverWritePolicy"] = "WrapsWhenFull";
+            asyncResp->res.jsonValue["Entries"] = {
+                {"@odata.id",
+                 "/redfish/v1/Systems/system/LogServices/EventLog/Entries"}};
+            asyncResp->res.jsonValue["Actions"]["#LogService.ClearLog"] = {
+
+                {"target", "/redfish/v1/Systems/system/LogServices/EventLog/"
+                           "Actions/LogService.ClearLog"}};
+        });
+}
+
+inline void requestRoutesJournalEventLogClear(App& app)
+{
+    BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/LogServices/EventLog/Actions/"
+                      "LogService.ClearLog/")
+        .privileges({"ConfigureComponents"})
+        .methods(boost::beast::http::verb::post)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                // Clear the EventLog by deleting the log files
+                std::vector<std::filesystem::path> redfishLogFiles;
+                if (getRedfishLogFiles(redfishLogFiles))
                 {
-                    if (pathStr.find("PostCode") != std::string::npos)
+                    for (const std::filesystem::path& file : redfishLogFiles)
                     {
-                        nlohmann::json& logServiceArrayLocal =
-                            asyncResp->res.jsonValue["Members"];
-                        logServiceArrayLocal.push_back(
-                            {{"@odata.id", "/redfish/v1/Systems/system/"
-                                           "LogServices/PostCodes"}});
-                        asyncResp->res.jsonValue["Members@odata.count"] =
-                            logServiceArrayLocal.size();
-                        return;
+                        std::error_code ec;
+                        std::filesystem::remove(file, ec);
                     }
                 }
-            },
-            "xyz.openbmc_project.ObjectMapper",
-            "/xyz/openbmc_project/object_mapper",
-            "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", "/", 0,
-            std::array<const char*, 1>{postCodeIface});
-    }
-};
 
-class EventLogService : public Node
-{
-  public:
-    EventLogService(App& app) :
-        Node(app, "/redfish/v1/Systems/system/LogServices/EventLog/")
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-    }
+                // Reload rsyslog so it knows to start new log files
+                crow::connections::systemBus->async_method_call(
+                    [asyncResp](const boost::system::error_code ec) {
+                        if (ec)
+                        {
+                            BMCWEB_LOG_ERROR << "Failed to reload rsyslog: "
+                                             << ec;
+                            messages::internalError(asyncResp->res);
+                            return;
+                        }
 
-  private:
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&, const std::vector<std::string>&) override
-    {
-        asyncResp->res.jsonValue["@odata.id"] =
-            "/redfish/v1/Systems/system/LogServices/EventLog";
-        asyncResp->res.jsonValue["@odata.type"] =
-            "#LogService.v1_1_0.LogService";
-        asyncResp->res.jsonValue["Name"] = "Event Log Service";
-        asyncResp->res.jsonValue["Description"] = "System Event Log Service";
-        asyncResp->res.jsonValue["Id"] = "EventLog";
-        asyncResp->res.jsonValue["OverWritePolicy"] = "WrapsWhenFull";
-        asyncResp->res.jsonValue["Entries"] = {
-            {"@odata.id",
-             "/redfish/v1/Systems/system/LogServices/EventLog/Entries"}};
-        asyncResp->res.jsonValue["Actions"]["#LogService.ClearLog"] = {
-
-            {"target", "/redfish/v1/Systems/system/LogServices/EventLog/"
-                       "Actions/LogService.ClearLog"}};
-    }
-};
-
-class JournalEventLogClear : public Node
-{
-  public:
-    JournalEventLogClear(App& app) :
-        Node(app, "/redfish/v1/Systems/system/LogServices/EventLog/Actions/"
-                  "LogService.ClearLog/")
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
-    }
-
-  private:
-    void doPost(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                const crow::Request&, const std::vector<std::string>&) override
-    {
-
-        // Clear the EventLog by deleting the log files
-        std::vector<std::filesystem::path> redfishLogFiles;
-        if (getRedfishLogFiles(redfishLogFiles))
-        {
-            for (const std::filesystem::path& file : redfishLogFiles)
-            {
-                std::error_code ec;
-                std::filesystem::remove(file, ec);
-            }
-        }
-
-        // Reload rsyslog so it knows to start new log files
-        crow::connections::systemBus->async_method_call(
-            [asyncResp](const boost::system::error_code ec) {
-                if (ec)
-                {
-                    BMCWEB_LOG_ERROR << "Failed to reload rsyslog: " << ec;
-                    messages::internalError(asyncResp->res);
-                    return;
-                }
-
-                messages::success(asyncResp->res);
-            },
-            "org.freedesktop.systemd1", "/org/freedesktop/systemd1",
-            "org.freedesktop.systemd1.Manager", "ReloadUnit", "rsyslog.service",
-            "replace");
-    }
-};
+                        messages::success(asyncResp->res);
+                    },
+                    "org.freedesktop.systemd1", "/org/freedesktop/systemd1",
+                    "org.freedesktop.systemd1.Manager", "ReloadUnit",
+                    "rsyslog.service", "replace");
+            });
+}
 
 static int fillEventLogEntryJson(const std::string& logEntryID,
                                  const std::string& logEntry,
@@ -1164,800 +1138,718 @@
     return 0;
 }
 
-class JournalEventLogEntryCollection : public Node
+inline void requestRoutesJournalEventLogEntryCollection(App& app)
 {
-  public:
-    JournalEventLogEntryCollection(App& app) :
-        Node(app, "/redfish/v1/Systems/system/LogServices/EventLog/Entries/")
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-    }
-
-  private:
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request& req,
-               const std::vector<std::string>&) override
-    {
-        uint64_t skip = 0;
-        uint64_t top = maxEntriesPerPage; // Show max entries by default
-        if (!getSkipParam(asyncResp, req, skip))
-        {
-            return;
-        }
-        if (!getTopParam(asyncResp, req, top))
-        {
-            return;
-        }
-        // Collections don't include the static data added by SubRoute because
-        // it has a duplicate entry for members
-        asyncResp->res.jsonValue["@odata.type"] =
-            "#LogEntryCollection.LogEntryCollection";
-        asyncResp->res.jsonValue["@odata.id"] =
-            "/redfish/v1/Systems/system/LogServices/EventLog/Entries";
-        asyncResp->res.jsonValue["Name"] = "System Event Log Entries";
-        asyncResp->res.jsonValue["Description"] =
-            "Collection of System Event Log Entries";
-
-        nlohmann::json& logEntryArray = asyncResp->res.jsonValue["Members"];
-        logEntryArray = nlohmann::json::array();
-        // Go through the log files and create a unique ID for each entry
-        std::vector<std::filesystem::path> redfishLogFiles;
-        getRedfishLogFiles(redfishLogFiles);
-        uint64_t entryCount = 0;
-        std::string logEntry;
-
-        // Oldest logs are in the last file, so start there and loop backwards
-        for (auto it = redfishLogFiles.rbegin(); it < redfishLogFiles.rend();
-             it++)
-        {
-            std::ifstream logStream(*it);
-            if (!logStream.is_open())
-            {
-                continue;
-            }
-
-            // Reset the unique ID on the first entry
-            bool firstEntry = true;
-            while (std::getline(logStream, logEntry))
-            {
-                entryCount++;
-                // Handle paging using skip (number of entries to skip from the
-                // start) and top (number of entries to display)
-                if (entryCount <= skip || entryCount > skip + top)
+    BMCWEB_ROUTE(app,
+                 "/redfish/v1/Systems/system/LogServices/EventLog/Entries/")
+        .privileges({"Login"})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request& req,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                uint64_t skip = 0;
+                uint64_t top = maxEntriesPerPage; // Show max entries by default
+                if (!getSkipParam(asyncResp, req, skip))
                 {
-                    continue;
-                }
-
-                std::string idStr;
-                if (!getUniqueEntryID(logEntry, idStr, firstEntry))
-                {
-                    continue;
-                }
-
-                if (firstEntry)
-                {
-                    firstEntry = false;
-                }
-
-                logEntryArray.push_back({});
-                nlohmann::json& bmcLogEntry = logEntryArray.back();
-                if (fillEventLogEntryJson(idStr, logEntry, bmcLogEntry) != 0)
-                {
-                    messages::internalError(asyncResp->res);
                     return;
                 }
-            }
-        }
-        asyncResp->res.jsonValue["Members@odata.count"] = entryCount;
-        if (skip + top < entryCount)
-        {
-            asyncResp->res.jsonValue["Members@odata.nextLink"] =
-                "/redfish/v1/Systems/system/LogServices/EventLog/"
-                "Entries?$skip=" +
-                std::to_string(skip + top);
-        }
-    }
-};
-
-class JournalEventLogEntry : public Node
-{
-  public:
-    JournalEventLogEntry(App& app) :
-        Node(app,
-             "/redfish/v1/Systems/system/LogServices/EventLog/Entries/<str>/",
-             std::string())
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-    }
-
-  private:
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&,
-               const std::vector<std::string>& params) override
-    {
-
-        if (params.size() != 1)
-        {
-            messages::internalError(asyncResp->res);
-            return;
-        }
-        const std::string& targetID = params[0];
-
-        // Go through the log files and check the unique ID for each entry to
-        // find the target entry
-        std::vector<std::filesystem::path> redfishLogFiles;
-        getRedfishLogFiles(redfishLogFiles);
-        std::string logEntry;
-
-        // Oldest logs are in the last file, so start there and loop backwards
-        for (auto it = redfishLogFiles.rbegin(); it < redfishLogFiles.rend();
-             it++)
-        {
-            std::ifstream logStream(*it);
-            if (!logStream.is_open())
-            {
-                continue;
-            }
-
-            // Reset the unique ID on the first entry
-            bool firstEntry = true;
-            while (std::getline(logStream, logEntry))
-            {
-                std::string idStr;
-                if (!getUniqueEntryID(logEntry, idStr, firstEntry))
+                if (!getTopParam(asyncResp, req, top))
                 {
-                    continue;
-                }
-
-                if (firstEntry)
-                {
-                    firstEntry = false;
-                }
-
-                if (idStr == targetID)
-                {
-                    if (fillEventLogEntryJson(idStr, logEntry,
-                                              asyncResp->res.jsonValue) != 0)
-                    {
-                        messages::internalError(asyncResp->res);
-                        return;
-                    }
                     return;
                 }
-            }
-        }
-        // Requested ID was not found
-        messages::resourceMissingAtURI(asyncResp->res, targetID);
-    }
-};
+                // Collections don't include the static data added by SubRoute
+                // because it has a duplicate entry for members
+                asyncResp->res.jsonValue["@odata.type"] =
+                    "#LogEntryCollection.LogEntryCollection";
+                asyncResp->res.jsonValue["@odata.id"] =
+                    "/redfish/v1/Systems/system/LogServices/EventLog/Entries";
+                asyncResp->res.jsonValue["Name"] = "System Event Log Entries";
+                asyncResp->res.jsonValue["Description"] =
+                    "Collection of System Event Log Entries";
 
-class DBusEventLogEntryCollection : public Node
-{
-  public:
-    DBusEventLogEntryCollection(App& app) :
-        Node(app, "/redfish/v1/Systems/system/LogServices/EventLog/Entries/")
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-    }
-
-  private:
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&, const std::vector<std::string>&) override
-    {
-
-        // Collections don't include the static data added by SubRoute because
-        // it has a duplicate entry for members
-        asyncResp->res.jsonValue["@odata.type"] =
-            "#LogEntryCollection.LogEntryCollection";
-        asyncResp->res.jsonValue["@odata.id"] =
-            "/redfish/v1/Systems/system/LogServices/EventLog/Entries";
-        asyncResp->res.jsonValue["Name"] = "System Event Log Entries";
-        asyncResp->res.jsonValue["Description"] =
-            "Collection of System Event Log Entries";
-
-        // DBus implementation of EventLog/Entries
-        // Make call to Logging Service to find all log entry objects
-        crow::connections::systemBus->async_method_call(
-            [asyncResp](const boost::system::error_code ec,
-                        GetManagedObjectsType& resp) {
-                if (ec)
-                {
-                    // TODO Handle for specific error code
-                    BMCWEB_LOG_ERROR
-                        << "getLogEntriesIfaceData resp_handler got error "
-                        << ec;
-                    messages::internalError(asyncResp->res);
-                    return;
-                }
-                nlohmann::json& entriesArray =
+                nlohmann::json& logEntryArray =
                     asyncResp->res.jsonValue["Members"];
-                entriesArray = nlohmann::json::array();
-                for (auto& objectPath : resp)
+                logEntryArray = nlohmann::json::array();
+                // Go through the log files and create a unique ID for each
+                // entry
+                std::vector<std::filesystem::path> redfishLogFiles;
+                getRedfishLogFiles(redfishLogFiles);
+                uint64_t entryCount = 0;
+                std::string logEntry;
+
+                // Oldest logs are in the last file, so start there and loop
+                // backwards
+                for (auto it = redfishLogFiles.rbegin();
+                     it < redfishLogFiles.rend(); it++)
                 {
-                    uint32_t* id = nullptr;
-                    std::time_t timestamp{};
-                    std::time_t updateTimestamp{};
-                    std::string* severity = nullptr;
-                    std::string* message = nullptr;
-                    std::string* filePath = nullptr;
-                    bool resolved = false;
-                    for (auto& interfaceMap : objectPath.second)
-                    {
-                        if (interfaceMap.first ==
-                            "xyz.openbmc_project.Logging.Entry")
-                        {
-                            for (auto& propertyMap : interfaceMap.second)
-                            {
-                                if (propertyMap.first == "Id")
-                                {
-                                    id = std::get_if<uint32_t>(
-                                        &propertyMap.second);
-                                }
-                                else if (propertyMap.first == "Timestamp")
-                                {
-                                    const uint64_t* millisTimeStamp =
-                                        std::get_if<uint64_t>(
-                                            &propertyMap.second);
-                                    if (millisTimeStamp != nullptr)
-                                    {
-                                        timestamp = crow::utility::getTimestamp(
-                                            *millisTimeStamp);
-                                    }
-                                }
-                                else if (propertyMap.first == "UpdateTimestamp")
-                                {
-                                    const uint64_t* millisTimeStamp =
-                                        std::get_if<uint64_t>(
-                                            &propertyMap.second);
-                                    if (millisTimeStamp != nullptr)
-                                    {
-                                        updateTimestamp =
-                                            crow::utility::getTimestamp(
-                                                *millisTimeStamp);
-                                    }
-                                }
-                                else if (propertyMap.first == "Severity")
-                                {
-                                    severity = std::get_if<std::string>(
-                                        &propertyMap.second);
-                                }
-                                else if (propertyMap.first == "Message")
-                                {
-                                    message = std::get_if<std::string>(
-                                        &propertyMap.second);
-                                }
-                                else if (propertyMap.first == "Resolved")
-                                {
-                                    bool* resolveptr =
-                                        std::get_if<bool>(&propertyMap.second);
-                                    if (resolveptr == nullptr)
-                                    {
-                                        messages::internalError(asyncResp->res);
-                                        return;
-                                    }
-                                    resolved = *resolveptr;
-                                }
-                            }
-                            if (id == nullptr || message == nullptr ||
-                                severity == nullptr)
-                            {
-                                messages::internalError(asyncResp->res);
-                                return;
-                            }
-                        }
-                        else if (interfaceMap.first ==
-                                 "xyz.openbmc_project.Common.FilePath")
-                        {
-                            for (auto& propertyMap : interfaceMap.second)
-                            {
-                                if (propertyMap.first == "Path")
-                                {
-                                    filePath = std::get_if<std::string>(
-                                        &propertyMap.second);
-                                }
-                            }
-                        }
-                    }
-                    // Object path without the xyz.openbmc_project.Logging.Entry
-                    // interface, ignore and continue.
-                    if (id == nullptr || message == nullptr ||
-                        severity == nullptr)
+                    std::ifstream logStream(*it);
+                    if (!logStream.is_open())
                     {
                         continue;
                     }
-                    entriesArray.push_back({});
-                    nlohmann::json& thisEntry = entriesArray.back();
-                    thisEntry["@odata.type"] = "#LogEntry.v1_8_0.LogEntry";
-                    thisEntry["@odata.id"] = "/redfish/v1/Systems/system/"
-                                             "LogServices/EventLog/Entries/" +
-                                             std::to_string(*id);
-                    thisEntry["Name"] = "System Event Log Entry";
-                    thisEntry["Id"] = std::to_string(*id);
-                    thisEntry["Message"] = *message;
-                    thisEntry["Resolved"] = resolved;
-                    thisEntry["EntryType"] = "Event";
-                    thisEntry["Severity"] =
-                        translateSeverityDbusToRedfish(*severity);
-                    thisEntry["Created"] =
-                        crow::utility::getDateTime(timestamp);
-                    thisEntry["Modified"] =
-                        crow::utility::getDateTime(updateTimestamp);
-                    if (filePath != nullptr)
+
+                    // Reset the unique ID on the first entry
+                    bool firstEntry = true;
+                    while (std::getline(logStream, logEntry))
                     {
-                        thisEntry["AdditionalDataURI"] =
-                            "/redfish/v1/Systems/system/LogServices/EventLog/"
-                            "Entries/" +
-                            std::to_string(*id) + "/attachment";
-                    }
-                }
-                std::sort(entriesArray.begin(), entriesArray.end(),
-                          [](const nlohmann::json& left,
-                             const nlohmann::json& right) {
-                              return (left["Id"] <= right["Id"]);
-                          });
-                asyncResp->res.jsonValue["Members@odata.count"] =
-                    entriesArray.size();
-            },
-            "xyz.openbmc_project.Logging", "/xyz/openbmc_project/logging",
-            "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
-    }
-};
-
-class DBusEventLogEntry : public Node
-{
-  public:
-    DBusEventLogEntry(App& app) :
-        Node(app,
-             "/redfish/v1/Systems/system/LogServices/EventLog/Entries/<str>/",
-             std::string())
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-    }
-
-  private:
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&,
-               const std::vector<std::string>& params) override
-    {
-
-        if (params.size() != 1)
-        {
-            messages::internalError(asyncResp->res);
-            return;
-        }
-        std::string entryID = params[0];
-        dbus::utility::escapePathForDbus(entryID);
-
-        // DBus implementation of EventLog/Entries
-        // Make call to Logging Service to find all log entry objects
-        crow::connections::systemBus->async_method_call(
-            [asyncResp, entryID](const boost::system::error_code ec,
-                                 GetManagedPropertyType& resp) {
-                if (ec.value() == EBADR)
-                {
-                    messages::resourceNotFound(asyncResp->res, "EventLogEntry",
-                                               entryID);
-                    return;
-                }
-                if (ec)
-                {
-                    BMCWEB_LOG_ERROR
-                        << "EventLogEntry (DBus) resp_handler got error " << ec;
-                    messages::internalError(asyncResp->res);
-                    return;
-                }
-                uint32_t* id = nullptr;
-                std::time_t timestamp{};
-                std::time_t updateTimestamp{};
-                std::string* severity = nullptr;
-                std::string* message = nullptr;
-                std::string* filePath = nullptr;
-                bool resolved = false;
-
-                for (auto& propertyMap : resp)
-                {
-                    if (propertyMap.first == "Id")
-                    {
-                        id = std::get_if<uint32_t>(&propertyMap.second);
-                    }
-                    else if (propertyMap.first == "Timestamp")
-                    {
-                        const uint64_t* millisTimeStamp =
-                            std::get_if<uint64_t>(&propertyMap.second);
-                        if (millisTimeStamp != nullptr)
+                        entryCount++;
+                        // Handle paging using skip (number of entries to skip
+                        // from the start) and top (number of entries to
+                        // display)
+                        if (entryCount <= skip || entryCount > skip + top)
                         {
-                            timestamp =
-                                crow::utility::getTimestamp(*millisTimeStamp);
+                            continue;
                         }
-                    }
-                    else if (propertyMap.first == "UpdateTimestamp")
-                    {
-                        const uint64_t* millisTimeStamp =
-                            std::get_if<uint64_t>(&propertyMap.second);
-                        if (millisTimeStamp != nullptr)
+
+                        std::string idStr;
+                        if (!getUniqueEntryID(logEntry, idStr, firstEntry))
                         {
-                            updateTimestamp =
-                                crow::utility::getTimestamp(*millisTimeStamp);
+                            continue;
                         }
-                    }
-                    else if (propertyMap.first == "Severity")
-                    {
-                        severity =
-                            std::get_if<std::string>(&propertyMap.second);
-                    }
-                    else if (propertyMap.first == "Message")
-                    {
-                        message = std::get_if<std::string>(&propertyMap.second);
-                    }
-                    else if (propertyMap.first == "Resolved")
-                    {
-                        bool* resolveptr =
-                            std::get_if<bool>(&propertyMap.second);
-                        if (resolveptr == nullptr)
+
+                        if (firstEntry)
+                        {
+                            firstEntry = false;
+                        }
+
+                        logEntryArray.push_back({});
+                        nlohmann::json& bmcLogEntry = logEntryArray.back();
+                        if (fillEventLogEntryJson(idStr, logEntry,
+                                                  bmcLogEntry) != 0)
                         {
                             messages::internalError(asyncResp->res);
                             return;
                         }
-                        resolved = *resolveptr;
-                    }
-                    else if (propertyMap.first == "Path")
-                    {
-                        filePath =
-                            std::get_if<std::string>(&propertyMap.second);
                     }
                 }
-                if (id == nullptr || message == nullptr || severity == nullptr)
+                asyncResp->res.jsonValue["Members@odata.count"] = entryCount;
+                if (skip + top < entryCount)
                 {
-                    messages::internalError(asyncResp->res);
-                    return;
-                }
-                asyncResp->res.jsonValue["@odata.type"] =
-                    "#LogEntry.v1_8_0.LogEntry";
-                asyncResp->res.jsonValue["@odata.id"] =
-                    "/redfish/v1/Systems/system/LogServices/EventLog/Entries/" +
-                    std::to_string(*id);
-                asyncResp->res.jsonValue["Name"] = "System Event Log Entry";
-                asyncResp->res.jsonValue["Id"] = std::to_string(*id);
-                asyncResp->res.jsonValue["Message"] = *message;
-                asyncResp->res.jsonValue["Resolved"] = resolved;
-                asyncResp->res.jsonValue["EntryType"] = "Event";
-                asyncResp->res.jsonValue["Severity"] =
-                    translateSeverityDbusToRedfish(*severity);
-                asyncResp->res.jsonValue["Created"] =
-                    crow::utility::getDateTime(timestamp);
-                asyncResp->res.jsonValue["Modified"] =
-                    crow::utility::getDateTime(updateTimestamp);
-                if (filePath != nullptr)
-                {
-                    asyncResp->res.jsonValue["AdditionalDataURI"] =
+                    asyncResp->res.jsonValue["Members@odata.nextLink"] =
                         "/redfish/v1/Systems/system/LogServices/EventLog/"
-                        "Entries/" +
-                        std::to_string(*id) + "/attachment";
+                        "Entries?$skip=" +
+                        std::to_string(skip + top);
                 }
-            },
-            "xyz.openbmc_project.Logging",
-            "/xyz/openbmc_project/logging/entry/" + entryID,
-            "org.freedesktop.DBus.Properties", "GetAll", "");
-    }
+            });
+}
 
-    void doPatch(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                 const crow::Request& req,
-                 const std::vector<std::string>& params) override
-    {
+inline void requestRoutesJournalEventLogEntry(App& app)
+{
+    BMCWEB_ROUTE(
+        app, "/redfish/v1/Systems/system/LogServices/EventLog/Entries/<str>/")
+        .privileges({"Login"})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+               const std::string& param) {
+                const std::string& targetID = param;
 
-        if (params.size() != 1)
-        {
-            messages::internalError(asyncResp->res);
-            return;
-        }
-        std::string entryId = params[0];
+                // Go through the log files and check the unique ID for each
+                // entry to find the target entry
+                std::vector<std::filesystem::path> redfishLogFiles;
+                getRedfishLogFiles(redfishLogFiles);
+                std::string logEntry;
 
-        std::optional<bool> resolved;
+                // Oldest logs are in the last file, so start there and loop
+                // backwards
+                for (auto it = redfishLogFiles.rbegin();
+                     it < redfishLogFiles.rend(); it++)
+                {
+                    std::ifstream logStream(*it);
+                    if (!logStream.is_open())
+                    {
+                        continue;
+                    }
 
-        if (!json_util::readJson(req, asyncResp->res, "Resolved", resolved))
-        {
-            return;
-        }
+                    // Reset the unique ID on the first entry
+                    bool firstEntry = true;
+                    while (std::getline(logStream, logEntry))
+                    {
+                        std::string idStr;
+                        if (!getUniqueEntryID(logEntry, idStr, firstEntry))
+                        {
+                            continue;
+                        }
 
-        if (resolved)
-        {
-            BMCWEB_LOG_DEBUG << "Set Resolved";
+                        if (firstEntry)
+                        {
+                            firstEntry = false;
+                        }
 
+                        if (idStr == targetID)
+                        {
+                            if (fillEventLogEntryJson(
+                                    idStr, logEntry,
+                                    asyncResp->res.jsonValue) != 0)
+                            {
+                                messages::internalError(asyncResp->res);
+                                return;
+                            }
+                            return;
+                        }
+                    }
+                }
+                // Requested ID was not found
+                messages::resourceMissingAtURI(asyncResp->res, targetID);
+            });
+}
+
+inline void requestRoutesDBusEventLogEntryCollection(App& app)
+{
+    BMCWEB_ROUTE(app,
+                 "/redfish/v1/Systems/system/LogServices/EventLog/Entries/")
+        .privileges({"Login"})
+        .methods(
+            boost::beast::http::verb::
+                get)([](const crow::Request&,
+                        const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+            // Collections don't include the static data added by SubRoute
+            // because it has a duplicate entry for members
+            asyncResp->res.jsonValue["@odata.type"] =
+                "#LogEntryCollection.LogEntryCollection";
+            asyncResp->res.jsonValue["@odata.id"] =
+                "/redfish/v1/Systems/system/LogServices/EventLog/Entries";
+            asyncResp->res.jsonValue["Name"] = "System Event Log Entries";
+            asyncResp->res.jsonValue["Description"] =
+                "Collection of System Event Log Entries";
+
+            // DBus implementation of EventLog/Entries
+            // Make call to Logging Service to find all log entry objects
             crow::connections::systemBus->async_method_call(
-                [asyncResp, resolved,
-                 entryId](const boost::system::error_code ec) {
+                [asyncResp](const boost::system::error_code ec,
+                            GetManagedObjectsType& resp) {
                     if (ec)
                     {
-                        BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
+                        // TODO Handle for specific error code
+                        BMCWEB_LOG_ERROR
+                            << "getLogEntriesIfaceData resp_handler got error "
+                            << ec;
                         messages::internalError(asyncResp->res);
                         return;
                     }
+                    nlohmann::json& entriesArray =
+                        asyncResp->res.jsonValue["Members"];
+                    entriesArray = nlohmann::json::array();
+                    for (auto& objectPath : resp)
+                    {
+                        uint32_t* id = nullptr;
+                        std::time_t timestamp{};
+                        std::time_t updateTimestamp{};
+                        std::string* severity = nullptr;
+                        std::string* message = nullptr;
+                        std::string* filePath = nullptr;
+                        bool resolved = false;
+                        for (auto& interfaceMap : objectPath.second)
+                        {
+                            if (interfaceMap.first ==
+                                "xyz.openbmc_project.Logging.Entry")
+                            {
+                                for (auto& propertyMap : interfaceMap.second)
+                                {
+                                    if (propertyMap.first == "Id")
+                                    {
+                                        id = std::get_if<uint32_t>(
+                                            &propertyMap.second);
+                                    }
+                                    else if (propertyMap.first == "Timestamp")
+                                    {
+                                        const uint64_t* millisTimeStamp =
+                                            std::get_if<uint64_t>(
+                                                &propertyMap.second);
+                                        if (millisTimeStamp != nullptr)
+                                        {
+                                            timestamp =
+                                                crow::utility::getTimestamp(
+                                                    *millisTimeStamp);
+                                        }
+                                    }
+                                    else if (propertyMap.first ==
+                                             "UpdateTimestamp")
+                                    {
+                                        const uint64_t* millisTimeStamp =
+                                            std::get_if<uint64_t>(
+                                                &propertyMap.second);
+                                        if (millisTimeStamp != nullptr)
+                                        {
+                                            updateTimestamp =
+                                                crow::utility::getTimestamp(
+                                                    *millisTimeStamp);
+                                        }
+                                    }
+                                    else if (propertyMap.first == "Severity")
+                                    {
+                                        severity = std::get_if<std::string>(
+                                            &propertyMap.second);
+                                    }
+                                    else if (propertyMap.first == "Message")
+                                    {
+                                        message = std::get_if<std::string>(
+                                            &propertyMap.second);
+                                    }
+                                    else if (propertyMap.first == "Resolved")
+                                    {
+                                        bool* resolveptr = std::get_if<bool>(
+                                            &propertyMap.second);
+                                        if (resolveptr == nullptr)
+                                        {
+                                            messages::internalError(
+                                                asyncResp->res);
+                                            return;
+                                        }
+                                        resolved = *resolveptr;
+                                    }
+                                }
+                                if (id == nullptr || message == nullptr ||
+                                    severity == nullptr)
+                                {
+                                    messages::internalError(asyncResp->res);
+                                    return;
+                                }
+                            }
+                            else if (interfaceMap.first ==
+                                     "xyz.openbmc_project.Common.FilePath")
+                            {
+                                for (auto& propertyMap : interfaceMap.second)
+                                {
+                                    if (propertyMap.first == "Path")
+                                    {
+                                        filePath = std::get_if<std::string>(
+                                            &propertyMap.second);
+                                    }
+                                }
+                            }
+                        }
+                        // Object path without the
+                        // xyz.openbmc_project.Logging.Entry interface, ignore
+                        // and continue.
+                        if (id == nullptr || message == nullptr ||
+                            severity == nullptr)
+                        {
+                            continue;
+                        }
+                        entriesArray.push_back({});
+                        nlohmann::json& thisEntry = entriesArray.back();
+                        thisEntry["@odata.type"] = "#LogEntry.v1_8_0.LogEntry";
+                        thisEntry["@odata.id"] =
+                            "/redfish/v1/Systems/system/"
+                            "LogServices/EventLog/Entries/" +
+                            std::to_string(*id);
+                        thisEntry["Name"] = "System Event Log Entry";
+                        thisEntry["Id"] = std::to_string(*id);
+                        thisEntry["Message"] = *message;
+                        thisEntry["Resolved"] = resolved;
+                        thisEntry["EntryType"] = "Event";
+                        thisEntry["Severity"] =
+                            translateSeverityDbusToRedfish(*severity);
+                        thisEntry["Created"] =
+                            crow::utility::getDateTime(timestamp);
+                        thisEntry["Modified"] =
+                            crow::utility::getDateTime(updateTimestamp);
+                        if (filePath != nullptr)
+                        {
+                            thisEntry["AdditionalDataURI"] =
+                                "/redfish/v1/Systems/system/LogServices/"
+                                "EventLog/"
+                                "Entries/" +
+                                std::to_string(*id) + "/attachment";
+                        }
+                    }
+                    std::sort(entriesArray.begin(), entriesArray.end(),
+                              [](const nlohmann::json& left,
+                                 const nlohmann::json& right) {
+                                  return (left["Id"] <= right["Id"]);
+                              });
+                    asyncResp->res.jsonValue["Members@odata.count"] =
+                        entriesArray.size();
                 },
-                "xyz.openbmc_project.Logging",
-                "/xyz/openbmc_project/logging/entry/" + entryId,
-                "org.freedesktop.DBus.Properties", "Set",
-                "xyz.openbmc_project.Logging.Entry", "Resolved",
-                std::variant<bool>(*resolved));
-        }
-    }
+                "xyz.openbmc_project.Logging", "/xyz/openbmc_project/logging",
+                "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
+        });
+}
 
-    void doDelete(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                  const crow::Request&,
-                  const std::vector<std::string>& params) override
-    {
-
-        BMCWEB_LOG_DEBUG << "Do delete single event entries.";
-
-        if (params.size() != 1)
-        {
-            messages::internalError(asyncResp->res);
-            return;
-        }
-        std::string entryID = params[0];
-
-        dbus::utility::escapePathForDbus(entryID);
-
-        // Process response from Logging service.
-        auto respHandler = [asyncResp,
-                            entryID](const boost::system::error_code ec) {
-            BMCWEB_LOG_DEBUG << "EventLogEntry (DBus) doDelete callback: Done";
-            if (ec)
-            {
-                if (ec.value() == EBADR)
-                {
-                    messages::resourceNotFound(asyncResp->res, "LogEntry",
-                                               entryID);
-                    return;
-                }
-                // TODO Handle for specific error code
-                BMCWEB_LOG_ERROR
-                    << "EventLogEntry (DBus) doDelete respHandler got error "
-                    << ec;
-                asyncResp->res.result(
-                    boost::beast::http::status::internal_server_error);
-                return;
-            }
-
-            asyncResp->res.result(boost::beast::http::status::ok);
-        };
-
-        // Make call to Logging service to request Delete Log
-        crow::connections::systemBus->async_method_call(
-            respHandler, "xyz.openbmc_project.Logging",
-            "/xyz/openbmc_project/logging/entry/" + entryID,
-            "xyz.openbmc_project.Object.Delete", "Delete");
-    }
-};
-
-class DBusEventLogEntryDownload : public Node
+inline void requestRoutesDBusEventLogEntry(App& app)
 {
-  public:
-    DBusEventLogEntryDownload(App& app) :
-        Node(app,
-             "/redfish/v1/Systems/system/LogServices/EventLog/Entries/<str>/"
-             "attachment",
-             std::string())
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-    }
+    BMCWEB_ROUTE(
+        app, "/redfish/v1/Systems/system/LogServices/EventLog/Entries/<str>/")
+        .privileges({"Login"})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+               const std::string& param)
 
-  private:
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request& req,
-               const std::vector<std::string>& params) override
-    {
-        if (params.size() != 1)
-        {
-            messages::internalError(asyncResp->res);
-            return;
-        }
-
-        std::string_view acceptHeader = req.getHeaderValue("Accept");
-        // The iterators in boost/http/rfc7230.hpp end the string if '/' is
-        // found, so replace it with arbitrary character '|' which is not part
-        // of the Accept header syntax.
-        std::string acceptStr =
-            boost::replace_all_copy(std::string(acceptHeader), "/", "|");
-        boost::beast::http::ext_list acceptTypes{acceptStr};
-        bool supported = false;
-        for (const auto& type : acceptTypes)
-        {
-            if ((type.first == "*|*") ||
-                (type.first == "application|octet-stream"))
             {
-                supported = true;
-                break;
-            }
-        }
-        if (!supported)
-        {
-            asyncResp->res.result(boost::beast::http::status::bad_request);
-            return;
-        }
+                std::string entryID = param;
+                dbus::utility::escapePathForDbus(entryID);
 
-        std::string entryID = params[0];
-        dbus::utility::escapePathForDbus(entryID);
+                // DBus implementation of EventLog/Entries
+                // Make call to Logging Service to find all log entry objects
+                crow::connections::systemBus->async_method_call(
+                    [asyncResp, entryID](const boost::system::error_code ec,
+                                         GetManagedPropertyType& resp) {
+                        if (ec.value() == EBADR)
+                        {
+                            messages::resourceNotFound(
+                                asyncResp->res, "EventLogEntry", entryID);
+                            return;
+                        }
+                        if (ec)
+                        {
+                            BMCWEB_LOG_ERROR << "EventLogEntry (DBus) "
+                                                "resp_handler got error "
+                                             << ec;
+                            messages::internalError(asyncResp->res);
+                            return;
+                        }
+                        uint32_t* id = nullptr;
+                        std::time_t timestamp{};
+                        std::time_t updateTimestamp{};
+                        std::string* severity = nullptr;
+                        std::string* message = nullptr;
+                        std::string* filePath = nullptr;
+                        bool resolved = false;
 
-        crow::connections::systemBus->async_method_call(
-            [asyncResp, entryID](const boost::system::error_code ec,
-                                 const sdbusplus::message::unix_fd& unixfd) {
-                if (ec.value() == EBADR)
+                        for (auto& propertyMap : resp)
+                        {
+                            if (propertyMap.first == "Id")
+                            {
+                                id = std::get_if<uint32_t>(&propertyMap.second);
+                            }
+                            else if (propertyMap.first == "Timestamp")
+                            {
+                                const uint64_t* millisTimeStamp =
+                                    std::get_if<uint64_t>(&propertyMap.second);
+                                if (millisTimeStamp != nullptr)
+                                {
+                                    timestamp = crow::utility::getTimestamp(
+                                        *millisTimeStamp);
+                                }
+                            }
+                            else if (propertyMap.first == "UpdateTimestamp")
+                            {
+                                const uint64_t* millisTimeStamp =
+                                    std::get_if<uint64_t>(&propertyMap.second);
+                                if (millisTimeStamp != nullptr)
+                                {
+                                    updateTimestamp =
+                                        crow::utility::getTimestamp(
+                                            *millisTimeStamp);
+                                }
+                            }
+                            else if (propertyMap.first == "Severity")
+                            {
+                                severity = std::get_if<std::string>(
+                                    &propertyMap.second);
+                            }
+                            else if (propertyMap.first == "Message")
+                            {
+                                message = std::get_if<std::string>(
+                                    &propertyMap.second);
+                            }
+                            else if (propertyMap.first == "Resolved")
+                            {
+                                bool* resolveptr =
+                                    std::get_if<bool>(&propertyMap.second);
+                                if (resolveptr == nullptr)
+                                {
+                                    messages::internalError(asyncResp->res);
+                                    return;
+                                }
+                                resolved = *resolveptr;
+                            }
+                            else if (propertyMap.first == "Path")
+                            {
+                                filePath = std::get_if<std::string>(
+                                    &propertyMap.second);
+                            }
+                        }
+                        if (id == nullptr || message == nullptr ||
+                            severity == nullptr)
+                        {
+                            messages::internalError(asyncResp->res);
+                            return;
+                        }
+                        asyncResp->res.jsonValue["@odata.type"] =
+                            "#LogEntry.v1_8_0.LogEntry";
+                        asyncResp->res.jsonValue["@odata.id"] =
+                            "/redfish/v1/Systems/system/LogServices/EventLog/"
+                            "Entries/" +
+                            std::to_string(*id);
+                        asyncResp->res.jsonValue["Name"] =
+                            "System Event Log Entry";
+                        asyncResp->res.jsonValue["Id"] = std::to_string(*id);
+                        asyncResp->res.jsonValue["Message"] = *message;
+                        asyncResp->res.jsonValue["Resolved"] = resolved;
+                        asyncResp->res.jsonValue["EntryType"] = "Event";
+                        asyncResp->res.jsonValue["Severity"] =
+                            translateSeverityDbusToRedfish(*severity);
+                        asyncResp->res.jsonValue["Created"] =
+                            crow::utility::getDateTime(timestamp);
+                        asyncResp->res.jsonValue["Modified"] =
+                            crow::utility::getDateTime(updateTimestamp);
+                        if (filePath != nullptr)
+                        {
+                            asyncResp->res.jsonValue["AdditionalDataURI"] =
+                                "/redfish/v1/Systems/system/LogServices/"
+                                "EventLog/"
+                                "attachment/" +
+                                std::to_string(*id);
+                        }
+                    },
+                    "xyz.openbmc_project.Logging",
+                    "/xyz/openbmc_project/logging/entry/" + entryID,
+                    "org.freedesktop.DBus.Properties", "GetAll", "");
+            });
+
+    BMCWEB_ROUTE(
+        app, "/redfish/v1/Systems/system/LogServices/EventLog/Entries/<str>/")
+        .privileges({"ConfigureManager"})
+        .methods(boost::beast::http::verb::patch)(
+            [](const crow::Request& req,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+               const std::string& entryId) {
+                std::optional<bool> resolved;
+
+                if (!json_util::readJson(req, asyncResp->res, "Resolved",
+                                         resolved))
                 {
-                    messages::resourceNotFound(asyncResp->res,
-                                               "EventLogAttachment", entryID);
                     return;
                 }
-                if (ec)
-                {
-                    BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
-                    messages::internalError(asyncResp->res);
-                    return;
-                }
+                BMCWEB_LOG_DEBUG << "Set Resolved";
 
-                int fd = -1;
-                fd = dup(unixfd);
-                if (fd == -1)
-                {
-                    messages::internalError(asyncResp->res);
-                    return;
-                }
+                crow::connections::systemBus->async_method_call(
+                    [asyncResp, resolved,
+                     entryId](const boost::system::error_code ec) {
+                        if (ec)
+                        {
+                            BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
+                            messages::internalError(asyncResp->res);
+                            return;
+                        }
+                    },
+                    "xyz.openbmc_project.Logging",
+                    "/xyz/openbmc_project/logging/entry/" + entryId,
+                    "org.freedesktop.DBus.Properties", "Set",
+                    "xyz.openbmc_project.Logging.Entry", "Resolved",
+                    std::variant<bool>(*resolved));
+            });
 
-                long long int size = lseek(fd, 0, SEEK_END);
-                if (size == -1)
-                {
-                    messages::internalError(asyncResp->res);
-                    return;
-                }
+    BMCWEB_ROUTE(
+        app, "/redfish/v1/Systems/system/LogServices/EventLog/Entries/<str>/")
+        .privileges({"ConfigureManager"})
+        .methods(boost::beast::http::verb::delete_)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+               const std::string& param)
 
-                // Arbitrary max size of 64kb
-                constexpr int maxFileSize = 65536;
-                if (size > maxFileSize)
-                {
-                    BMCWEB_LOG_ERROR
-                        << "File size exceeds maximum allowed size of "
-                        << maxFileSize;
-                    messages::internalError(asyncResp->res);
-                    return;
-                }
-                std::vector<char> data(static_cast<size_t>(size));
-                long long int rc = lseek(fd, 0, SEEK_SET);
-                if (rc == -1)
-                {
-                    messages::internalError(asyncResp->res);
-                    return;
-                }
-                rc = read(fd, data.data(), data.size());
-                if ((rc == -1) || (rc != size))
-                {
-                    messages::internalError(asyncResp->res);
-                    return;
-                }
-                close(fd);
+            {
+                BMCWEB_LOG_DEBUG << "Do delete single event entries.";
 
-                std::string_view strData(data.data(), data.size());
-                std::string output = crow::utility::base64encode(strData);
+                std::string entryID = param;
 
-                asyncResp->res.addHeader("Content-Type",
-                                         "application/octet-stream");
-                asyncResp->res.addHeader("Content-Transfer-Encoding", "Base64");
-                asyncResp->res.body() = std::move(output);
-            },
-            "xyz.openbmc_project.Logging",
-            "/xyz/openbmc_project/logging/entry/" + entryID,
-            "xyz.openbmc_project.Logging.Entry", "GetEntry");
-    }
-};
+                dbus::utility::escapePathForDbus(entryID);
 
-class BMCLogServiceCollection : public Node
+                // Process response from Logging service.
+                auto respHandler = [asyncResp, entryID](
+                                       const boost::system::error_code ec) {
+                    BMCWEB_LOG_DEBUG
+                        << "EventLogEntry (DBus) doDelete callback: Done";
+                    if (ec)
+                    {
+                        if (ec.value() == EBADR)
+                        {
+                            messages::resourceNotFound(asyncResp->res,
+                                                       "LogEntry", entryID);
+                            return;
+                        }
+                        // TODO Handle for specific error code
+                        BMCWEB_LOG_ERROR << "EventLogEntry (DBus) doDelete "
+                                            "respHandler got error "
+                                         << ec;
+                        asyncResp->res.result(
+                            boost::beast::http::status::internal_server_error);
+                        return;
+                    }
+
+                    asyncResp->res.result(boost::beast::http::status::ok);
+                };
+
+                // Make call to Logging service to request Delete Log
+                crow::connections::systemBus->async_method_call(
+                    respHandler, "xyz.openbmc_project.Logging",
+                    "/xyz/openbmc_project/logging/entry/" + entryID,
+                    "xyz.openbmc_project.Object.Delete", "Delete");
+            });
+}
+
+inline void requestRoutesDBusEventLogEntryDownload(App& app)
 {
-  public:
-    BMCLogServiceCollection(App& app) :
-        Node(app, "/redfish/v1/Managers/bmc/LogServices/")
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-    }
+    BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/LogServices/EventLog/Entries/"
+                      "<str>/attachment")
+        .privileges({"Login"})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request& req,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+               const std::string& param)
 
-  private:
-    /**
-     * Functions triggers appropriate requests on DBus
-     */
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&, const std::vector<std::string>&) override
-    {
+            {
+                std::string_view acceptHeader = req.getHeaderValue("Accept");
+                // The iterators in boost/http/rfc7230.hpp end the string if '/'
+                // is found, so replace it with arbitrary character '|' which is
+                // not part of the Accept header syntax.
+                std::string acceptStr = boost::replace_all_copy(
+                    std::string(acceptHeader), "/", "|");
+                boost::beast::http::ext_list acceptTypes{acceptStr};
+                bool supported = false;
+                for (const auto& type : acceptTypes)
+                {
+                    if ((type.first == "*|*") ||
+                        (type.first == "application|octet-stream"))
+                    {
+                        supported = true;
+                        break;
+                    }
+                }
+                if (!supported)
+                {
+                    asyncResp->res.result(
+                        boost::beast::http::status::bad_request);
+                    return;
+                }
 
-        // Collections don't include the static data added by SubRoute because
-        // it has a duplicate entry for members
-        asyncResp->res.jsonValue["@odata.type"] =
-            "#LogServiceCollection.LogServiceCollection";
-        asyncResp->res.jsonValue["@odata.id"] =
-            "/redfish/v1/Managers/bmc/LogServices";
-        asyncResp->res.jsonValue["Name"] = "Open BMC Log Services Collection";
-        asyncResp->res.jsonValue["Description"] =
-            "Collection of LogServices for this Manager";
-        nlohmann::json& logServiceArray = asyncResp->res.jsonValue["Members"];
-        logServiceArray = nlohmann::json::array();
+                std::string entryID = param;
+                dbus::utility::escapePathForDbus(entryID);
+
+                crow::connections::systemBus->async_method_call(
+                    [asyncResp,
+                     entryID](const boost::system::error_code ec,
+                              const sdbusplus::message::unix_fd& unixfd) {
+                        if (ec.value() == EBADR)
+                        {
+                            messages::resourceNotFound(
+                                asyncResp->res, "EventLogAttachment", entryID);
+                            return;
+                        }
+                        if (ec)
+                        {
+                            BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
+                            messages::internalError(asyncResp->res);
+                            return;
+                        }
+
+                        int fd = -1;
+                        fd = dup(unixfd);
+                        if (fd == -1)
+                        {
+                            messages::internalError(asyncResp->res);
+                            return;
+                        }
+
+                        long long int size = lseek(fd, 0, SEEK_END);
+                        if (size == -1)
+                        {
+                            messages::internalError(asyncResp->res);
+                            return;
+                        }
+
+                        // Arbitrary max size of 64kb
+                        constexpr int maxFileSize = 65536;
+                        if (size > maxFileSize)
+                        {
+                            BMCWEB_LOG_ERROR
+                                << "File size exceeds maximum allowed size of "
+                                << maxFileSize;
+                            messages::internalError(asyncResp->res);
+                            return;
+                        }
+                        std::vector<char> data(static_cast<size_t>(size));
+                        long long int rc = lseek(fd, 0, SEEK_SET);
+                        if (rc == -1)
+                        {
+                            messages::internalError(asyncResp->res);
+                            return;
+                        }
+                        rc = read(fd, data.data(), data.size());
+                        if ((rc == -1) || (rc != size))
+                        {
+                            messages::internalError(asyncResp->res);
+                            return;
+                        }
+                        close(fd);
+
+                        std::string_view strData(data.data(), data.size());
+                        std::string output =
+                            crow::utility::base64encode(strData);
+
+                        asyncResp->res.addHeader("Content-Type",
+                                                 "application/octet-stream");
+                        asyncResp->res.addHeader("Content-Transfer-Encoding",
+                                                 "Base64");
+                        asyncResp->res.body() = std::move(output);
+                    },
+                    "xyz.openbmc_project.Logging",
+                    "/xyz/openbmc_project/logging/entry/" + entryID,
+                    "xyz.openbmc_project.Logging.Entry", "GetEntry");
+            });
+}
+
+inline void requestRoutesBMCLogServiceCollection(App& app)
+{
+    BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/LogServices/")
+        .privileges({"Login"})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                // Collections don't include the static data added by SubRoute
+                // because it has a duplicate entry for members
+                asyncResp->res.jsonValue["@odata.type"] =
+                    "#LogServiceCollection.LogServiceCollection";
+                asyncResp->res.jsonValue["@odata.id"] =
+                    "/redfish/v1/Managers/bmc/LogServices";
+                asyncResp->res.jsonValue["Name"] =
+                    "Open BMC Log Services Collection";
+                asyncResp->res.jsonValue["Description"] =
+                    "Collection of LogServices for this Manager";
+                nlohmann::json& logServiceArray =
+                    asyncResp->res.jsonValue["Members"];
+                logServiceArray = nlohmann::json::array();
 #ifdef BMCWEB_ENABLE_REDFISH_DUMP_LOG
-        logServiceArray.push_back(
-            {{"@odata.id", "/redfish/v1/Managers/bmc/LogServices/Dump"}});
+                logServiceArray.push_back(
+                    {{"@odata.id",
+                      "/redfish/v1/Managers/bmc/LogServices/Dump"}});
 #endif
 #ifdef BMCWEB_ENABLE_REDFISH_BMC_JOURNAL
-        logServiceArray.push_back(
-            {{"@odata.id", "/redfish/v1/Managers/bmc/LogServices/Journal"}});
+                logServiceArray.push_back(
+                    {{"@odata.id",
+                      "/redfish/v1/Managers/bmc/LogServices/Journal"}});
 #endif
-        asyncResp->res.jsonValue["Members@odata.count"] =
-            logServiceArray.size();
-    }
-};
+                asyncResp->res.jsonValue["Members@odata.count"] =
+                    logServiceArray.size();
+            });
+}
 
-class BMCJournalLogService : public Node
+inline void requestRoutesBMCJournalLogService(App& app)
 {
-  public:
-    BMCJournalLogService(App& app) :
-        Node(app, "/redfish/v1/Managers/bmc/LogServices/Journal/")
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-    }
+    BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/LogServices/Journal/")
+        .privileges({"Login"})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
 
-  private:
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&, const std::vector<std::string>&) override
-    {
-
-        asyncResp->res.jsonValue["@odata.type"] =
-            "#LogService.v1_1_0.LogService";
-        asyncResp->res.jsonValue["@odata.id"] =
-            "/redfish/v1/Managers/bmc/LogServices/Journal";
-        asyncResp->res.jsonValue["Name"] = "Open BMC Journal Log Service";
-        asyncResp->res.jsonValue["Description"] = "BMC Journal Log Service";
-        asyncResp->res.jsonValue["Id"] = "BMC Journal";
-        asyncResp->res.jsonValue["OverWritePolicy"] = "WrapsWhenFull";
-        asyncResp->res.jsonValue["Entries"] = {
-            {"@odata.id",
-             "/redfish/v1/Managers/bmc/LogServices/Journal/Entries"}};
-    }
-};
+            {
+                asyncResp->res.jsonValue["@odata.type"] =
+                    "#LogService.v1_1_0.LogService";
+                asyncResp->res.jsonValue["@odata.id"] =
+                    "/redfish/v1/Managers/bmc/LogServices/Journal";
+                asyncResp->res.jsonValue["Name"] =
+                    "Open BMC Journal Log Service";
+                asyncResp->res.jsonValue["Description"] =
+                    "BMC Journal Log Service";
+                asyncResp->res.jsonValue["Id"] = "BMC Journal";
+                asyncResp->res.jsonValue["OverWritePolicy"] = "WrapsWhenFull";
+                asyncResp->res.jsonValue["Entries"] = {
+                    {"@odata.id",
+                     "/redfish/v1/Managers/bmc/LogServices/Journal/Entries"}};
+            });
+}
 
 static int fillBMCJournalLogEntryJson(const std::string& bmcJournalLogEntryID,
                                       sd_journal* journal,
@@ -2020,619 +1912,432 @@
     return 0;
 }
 
-class BMCJournalLogEntryCollection : public Node
+inline void requestRoutesBMCJournalLogEntryCollection(App& app)
 {
-  public:
-    BMCJournalLogEntryCollection(App& app) :
-        Node(app, "/redfish/v1/Managers/bmc/LogServices/Journal/Entries/")
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-    }
+    BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/LogServices/Journal/Entries/")
+        .privileges({"Login"})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request& req,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                static constexpr const long maxEntriesPerPage = 1000;
+                uint64_t skip = 0;
+                uint64_t top = maxEntriesPerPage; // Show max entries by default
+                if (!getSkipParam(asyncResp, req, skip))
+                {
+                    return;
+                }
+                if (!getTopParam(asyncResp, req, top))
+                {
+                    return;
+                }
+                // Collections don't include the static data added by SubRoute
+                // because it has a duplicate entry for members
+                asyncResp->res.jsonValue["@odata.type"] =
+                    "#LogEntryCollection.LogEntryCollection";
+                asyncResp->res.jsonValue["@odata.id"] =
+                    "/redfish/v1/Managers/bmc/LogServices/Journal/Entries";
+                asyncResp->res.jsonValue["Name"] = "Open BMC Journal Entries";
+                asyncResp->res.jsonValue["Description"] =
+                    "Collection of BMC Journal Entries";
+                nlohmann::json& logEntryArray =
+                    asyncResp->res.jsonValue["Members"];
+                logEntryArray = nlohmann::json::array();
 
-  private:
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request& req,
-               const std::vector<std::string>&) override
-    {
+                // Go through the journal and use the timestamp to create a
+                // unique ID for each entry
+                sd_journal* journalTmp = nullptr;
+                int ret = sd_journal_open(&journalTmp, SD_JOURNAL_LOCAL_ONLY);
+                if (ret < 0)
+                {
+                    BMCWEB_LOG_ERROR << "failed to open journal: "
+                                     << strerror(-ret);
+                    messages::internalError(asyncResp->res);
+                    return;
+                }
+                std::unique_ptr<sd_journal, decltype(&sd_journal_close)>
+                    journal(journalTmp, sd_journal_close);
+                journalTmp = nullptr;
+                uint64_t entryCount = 0;
+                // Reset the unique ID on the first entry
+                bool firstEntry = true;
+                SD_JOURNAL_FOREACH(journal.get())
+                {
+                    entryCount++;
+                    // Handle paging using skip (number of entries to skip from
+                    // the start) and top (number of entries to display)
+                    if (entryCount <= skip || entryCount > skip + top)
+                    {
+                        continue;
+                    }
 
-        static constexpr const long maxEntriesPerPage = 1000;
-        uint64_t skip = 0;
-        uint64_t top = maxEntriesPerPage; // Show max entries by default
-        if (!getSkipParam(asyncResp, req, skip))
-        {
-            return;
-        }
-        if (!getTopParam(asyncResp, req, top))
-        {
-            return;
-        }
-        // Collections don't include the static data added by SubRoute because
-        // it has a duplicate entry for members
-        asyncResp->res.jsonValue["@odata.type"] =
-            "#LogEntryCollection.LogEntryCollection";
-        asyncResp->res.jsonValue["@odata.id"] =
-            "/redfish/v1/Managers/bmc/LogServices/Journal/Entries";
-        asyncResp->res.jsonValue["Name"] = "Open BMC Journal Entries";
-        asyncResp->res.jsonValue["Description"] =
-            "Collection of BMC Journal Entries";
-        nlohmann::json& logEntryArray = asyncResp->res.jsonValue["Members"];
-        logEntryArray = nlohmann::json::array();
+                    std::string idStr;
+                    if (!getUniqueEntryID(journal.get(), idStr, firstEntry))
+                    {
+                        continue;
+                    }
 
-        // Go through the journal and use the timestamp to create a unique ID
-        // for each entry
-        sd_journal* journalTmp = nullptr;
-        int ret = sd_journal_open(&journalTmp, SD_JOURNAL_LOCAL_ONLY);
-        if (ret < 0)
-        {
-            BMCWEB_LOG_ERROR << "failed to open journal: " << strerror(-ret);
-            messages::internalError(asyncResp->res);
-            return;
-        }
-        std::unique_ptr<sd_journal, decltype(&sd_journal_close)> journal(
-            journalTmp, sd_journal_close);
-        journalTmp = nullptr;
-        uint64_t entryCount = 0;
-        // Reset the unique ID on the first entry
-        bool firstEntry = true;
-        SD_JOURNAL_FOREACH(journal.get())
-        {
-            entryCount++;
-            // Handle paging using skip (number of entries to skip from the
-            // start) and top (number of entries to display)
-            if (entryCount <= skip || entryCount > skip + top)
-            {
-                continue;
-            }
+                    if (firstEntry)
+                    {
+                        firstEntry = false;
+                    }
 
-            std::string idStr;
-            if (!getUniqueEntryID(journal.get(), idStr, firstEntry))
-            {
-                continue;
-            }
+                    logEntryArray.push_back({});
+                    nlohmann::json& bmcJournalLogEntry = logEntryArray.back();
+                    if (fillBMCJournalLogEntryJson(idStr, journal.get(),
+                                                   bmcJournalLogEntry) != 0)
+                    {
+                        messages::internalError(asyncResp->res);
+                        return;
+                    }
+                }
+                asyncResp->res.jsonValue["Members@odata.count"] = entryCount;
+                if (skip + top < entryCount)
+                {
+                    asyncResp->res.jsonValue["Members@odata.nextLink"] =
+                        "/redfish/v1/Managers/bmc/LogServices/Journal/"
+                        "Entries?$skip=" +
+                        std::to_string(skip + top);
+                }
+            });
+}
 
-            if (firstEntry)
-            {
-                firstEntry = false;
-            }
-
-            logEntryArray.push_back({});
-            nlohmann::json& bmcJournalLogEntry = logEntryArray.back();
-            if (fillBMCJournalLogEntryJson(idStr, journal.get(),
-                                           bmcJournalLogEntry) != 0)
-            {
-                messages::internalError(asyncResp->res);
-                return;
-            }
-        }
-        asyncResp->res.jsonValue["Members@odata.count"] = entryCount;
-        if (skip + top < entryCount)
-        {
-            asyncResp->res.jsonValue["Members@odata.nextLink"] =
-                "/redfish/v1/Managers/bmc/LogServices/Journal/Entries?$skip=" +
-                std::to_string(skip + top);
-        }
-    }
-};
-
-class BMCJournalLogEntry : public Node
+inline void requestRoutesBMCJournalLogEntry(App& app)
 {
-  public:
-    BMCJournalLogEntry(App& app) :
-        Node(app, "/redfish/v1/Managers/bmc/LogServices/Journal/Entries/<str>/",
-             std::string())
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-    }
+    BMCWEB_ROUTE(app,
+                 "/redfish/v1/Managers/bmc/LogServices/Journal/Entries/<str>/")
+        .privileges({"Login"})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+               const std::string& entryID) {
+                // Convert the unique ID back to a timestamp to find the entry
+                uint64_t ts = 0;
+                uint64_t index = 0;
+                if (!getTimestampFromID(asyncResp, entryID, ts, index))
+                {
+                    return;
+                }
 
-  private:
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&,
-               const std::vector<std::string>& params) override
-    {
+                sd_journal* journalTmp = nullptr;
+                int ret = sd_journal_open(&journalTmp, SD_JOURNAL_LOCAL_ONLY);
+                if (ret < 0)
+                {
+                    BMCWEB_LOG_ERROR << "failed to open journal: "
+                                     << strerror(-ret);
+                    messages::internalError(asyncResp->res);
+                    return;
+                }
+                std::unique_ptr<sd_journal, decltype(&sd_journal_close)>
+                    journal(journalTmp, sd_journal_close);
+                journalTmp = nullptr;
+                // Go to the timestamp in the log and move to the entry at the
+                // index tracking the unique ID
+                std::string idStr;
+                bool firstEntry = true;
+                ret = sd_journal_seek_realtime_usec(journal.get(), ts);
+                if (ret < 0)
+                {
+                    BMCWEB_LOG_ERROR << "failed to seek to an entry in journal"
+                                     << strerror(-ret);
+                    messages::internalError(asyncResp->res);
+                    return;
+                }
+                for (uint64_t i = 0; i <= index; i++)
+                {
+                    sd_journal_next(journal.get());
+                    if (!getUniqueEntryID(journal.get(), idStr, firstEntry))
+                    {
+                        messages::internalError(asyncResp->res);
+                        return;
+                    }
+                    if (firstEntry)
+                    {
+                        firstEntry = false;
+                    }
+                }
+                // Confirm that the entry ID matches what was requested
+                if (idStr != entryID)
+                {
+                    messages::resourceMissingAtURI(asyncResp->res, entryID);
+                    return;
+                }
 
-        if (params.size() != 1)
-        {
-            messages::internalError(asyncResp->res);
-            return;
-        }
-        const std::string& entryID = params[0];
-        // Convert the unique ID back to a timestamp to find the entry
-        uint64_t ts = 0;
-        uint64_t index = 0;
-        if (!getTimestampFromID(asyncResp, entryID, ts, index))
-        {
-            return;
-        }
-
-        sd_journal* journalTmp = nullptr;
-        int ret = sd_journal_open(&journalTmp, SD_JOURNAL_LOCAL_ONLY);
-        if (ret < 0)
-        {
-            BMCWEB_LOG_ERROR << "failed to open journal: " << strerror(-ret);
-            messages::internalError(asyncResp->res);
-            return;
-        }
-        std::unique_ptr<sd_journal, decltype(&sd_journal_close)> journal(
-            journalTmp, sd_journal_close);
-        journalTmp = nullptr;
-        // Go to the timestamp in the log and move to the entry at the index
-        // tracking the unique ID
-        std::string idStr;
-        bool firstEntry = true;
-        ret = sd_journal_seek_realtime_usec(journal.get(), ts);
-        if (ret < 0)
-        {
-            BMCWEB_LOG_ERROR << "failed to seek to an entry in journal"
-                             << strerror(-ret);
-            messages::internalError(asyncResp->res);
-            return;
-        }
-        for (uint64_t i = 0; i <= index; i++)
-        {
-            sd_journal_next(journal.get());
-            if (!getUniqueEntryID(journal.get(), idStr, firstEntry))
-            {
-                messages::internalError(asyncResp->res);
-                return;
-            }
-            if (firstEntry)
-            {
-                firstEntry = false;
-            }
-        }
-        // Confirm that the entry ID matches what was requested
-        if (idStr != entryID)
-        {
-            messages::resourceMissingAtURI(asyncResp->res, entryID);
-            return;
-        }
-
-        if (fillBMCJournalLogEntryJson(entryID, journal.get(),
-                                       asyncResp->res.jsonValue) != 0)
-        {
-            messages::internalError(asyncResp->res);
-            return;
-        }
-    }
-};
-
-class BMCDumpService : public Node
-{
-  public:
-    BMCDumpService(App& app) :
-        Node(app, "/redfish/v1/Managers/bmc/LogServices/Dump/")
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-    }
-
-  private:
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&, const std::vector<std::string>&) override
-    {
-
-        asyncResp->res.jsonValue["@odata.id"] =
-            "/redfish/v1/Managers/bmc/LogServices/Dump";
-        asyncResp->res.jsonValue["@odata.type"] =
-            "#LogService.v1_2_0.LogService";
-        asyncResp->res.jsonValue["Name"] = "Dump LogService";
-        asyncResp->res.jsonValue["Description"] = "BMC Dump LogService";
-        asyncResp->res.jsonValue["Id"] = "Dump";
-        asyncResp->res.jsonValue["OverWritePolicy"] = "WrapsWhenFull";
-        asyncResp->res.jsonValue["Entries"] = {
-            {"@odata.id", "/redfish/v1/Managers/bmc/LogServices/Dump/Entries"}};
-        asyncResp->res.jsonValue["Actions"] = {
-            {"#LogService.ClearLog",
-             {{"target", "/redfish/v1/Managers/bmc/LogServices/Dump/"
-                         "Actions/LogService.ClearLog"}}},
-            {"#LogService.CollectDiagnosticData",
-             {{"target", "/redfish/v1/Managers/bmc/LogServices/Dump/"
-                         "Actions/LogService.CollectDiagnosticData"}}}};
-    }
-};
-
-class BMCDumpEntryCollection : public Node
-{
-  public:
-    BMCDumpEntryCollection(App& app) :
-        Node(app, "/redfish/v1/Managers/bmc/LogServices/Dump/Entries/")
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-    }
-
-  private:
-    /**
-     * Functions triggers appropriate requests on DBus
-     */
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&, const std::vector<std::string>&) override
-    {
-
-        asyncResp->res.jsonValue["@odata.type"] =
-            "#LogEntryCollection.LogEntryCollection";
-        asyncResp->res.jsonValue["@odata.id"] =
-            "/redfish/v1/Managers/bmc/LogServices/Dump/Entries";
-        asyncResp->res.jsonValue["Name"] = "BMC Dump Entries";
-        asyncResp->res.jsonValue["Description"] =
-            "Collection of BMC Dump Entries";
-
-        getDumpEntryCollection(asyncResp, "BMC");
-    }
-};
-
-class BMCDumpEntry : public Node
-{
-  public:
-    BMCDumpEntry(App& app) :
-        Node(app, "/redfish/v1/Managers/bmc/LogServices/Dump/Entries/<str>/",
-             std::string())
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-    }
-
-  private:
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&,
-               const std::vector<std::string>& params) override
-    {
-
-        if (params.size() != 1)
-        {
-            messages::internalError(asyncResp->res);
-            return;
-        }
-        getDumpEntryById(asyncResp, params[0], "BMC");
-    }
-
-    void doDelete(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                  const crow::Request&,
-                  const std::vector<std::string>& params) override
-    {
-
-        if (params.size() != 1)
-        {
-            messages::internalError(asyncResp->res);
-            return;
-        }
-        deleteDumpEntry(asyncResp, params[0], "bmc");
-    }
-};
-
-class BMCDumpCreate : public Node
-{
-  public:
-    BMCDumpCreate(App& app) :
-        Node(app, "/redfish/v1/Managers/bmc/LogServices/Dump/"
-                  "Actions/"
-                  "LogService.CollectDiagnosticData/")
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-    }
-
-  private:
-    void doPost(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                const crow::Request& req,
-                const std::vector<std::string>&) override
-    {
-        createDump(asyncResp, req, "BMC");
-    }
-};
-
-class BMCDumpClear : public Node
-{
-  public:
-    BMCDumpClear(App& app) :
-        Node(app, "/redfish/v1/Managers/bmc/LogServices/Dump/"
-                  "Actions/"
-                  "LogService.ClearLog/")
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-    }
-
-  private:
-    void doPost(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                const crow::Request&, const std::vector<std::string>&) override
-    {
-        clearDump(asyncResp, "BMC");
-    }
-};
-
-class SystemDumpService : public Node
-{
-  public:
-    SystemDumpService(App& app) :
-        Node(app, "/redfish/v1/Systems/system/LogServices/Dump/")
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-    }
-
-  private:
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&, const std::vector<std::string>&) override
-    {
-
-        asyncResp->res.jsonValue["@odata.id"] =
-            "/redfish/v1/Systems/system/LogServices/Dump";
-        asyncResp->res.jsonValue["@odata.type"] =
-            "#LogService.v1_2_0.LogService";
-        asyncResp->res.jsonValue["Name"] = "Dump LogService";
-        asyncResp->res.jsonValue["Description"] = "System Dump LogService";
-        asyncResp->res.jsonValue["Id"] = "Dump";
-        asyncResp->res.jsonValue["OverWritePolicy"] = "WrapsWhenFull";
-        asyncResp->res.jsonValue["Entries"] = {
-            {"@odata.id",
-             "/redfish/v1/Systems/system/LogServices/Dump/Entries"}};
-        asyncResp->res.jsonValue["Actions"] = {
-            {"#LogService.ClearLog",
-             {{"target", "/redfish/v1/Systems/system/LogServices/Dump/Actions/"
-                         "LogService.ClearLog"}}},
-            {"#LogService.CollectDiagnosticData",
-             {{"target", "/redfish/v1/Systems/system/LogServices/Dump/Actions/"
-                         "LogService.CollectDiagnosticData"}}}};
-    }
-};
-
-class SystemDumpEntryCollection : public Node
-{
-  public:
-    SystemDumpEntryCollection(App& app) :
-        Node(app, "/redfish/v1/Systems/system/LogServices/Dump/Entries/")
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-    }
-
-  private:
-    /**
-     * Functions triggers appropriate requests on DBus
-     */
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&, const std::vector<std::string>&) override
-    {
-
-        asyncResp->res.jsonValue["@odata.type"] =
-            "#LogEntryCollection.LogEntryCollection";
-        asyncResp->res.jsonValue["@odata.id"] =
-            "/redfish/v1/Systems/system/LogServices/Dump/Entries";
-        asyncResp->res.jsonValue["Name"] = "System Dump Entries";
-        asyncResp->res.jsonValue["Description"] =
-            "Collection of System Dump Entries";
-
-        getDumpEntryCollection(asyncResp, "System");
-    }
-};
-
-class SystemDumpEntry : public Node
-{
-  public:
-    SystemDumpEntry(App& app) :
-        Node(app, "/redfish/v1/Systems/system/LogServices/Dump/Entries/<str>/",
-             std::string())
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-    }
-
-  private:
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&,
-               const std::vector<std::string>& params) override
-    {
-
-        if (params.size() != 1)
-        {
-            messages::internalError(asyncResp->res);
-            return;
-        }
-        getDumpEntryById(asyncResp, params[0], "System");
-    }
-
-    void doDelete(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                  const crow::Request&,
-                  const std::vector<std::string>& params) override
-    {
-
-        if (params.size() != 1)
-        {
-            messages::internalError(asyncResp->res);
-            return;
-        }
-        deleteDumpEntry(asyncResp, params[0], "system");
-    }
-};
-
-class SystemDumpCreate : public Node
-{
-  public:
-    SystemDumpCreate(App& app) :
-        Node(app, "/redfish/v1/Systems/system/LogServices/Dump/"
-                  "Actions/"
-                  "LogService.CollectDiagnosticData/")
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-    }
-
-  private:
-    void doPost(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                const crow::Request& req,
-                const std::vector<std::string>&) override
-    {
-        createDump(asyncResp, req, "System");
-    }
-};
-
-class SystemDumpClear : public Node
-{
-  public:
-    SystemDumpClear(App& app) :
-        Node(app, "/redfish/v1/Systems/system/LogServices/Dump/"
-                  "Actions/"
-                  "LogService.ClearLog/")
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-    }
-
-  private:
-    void doPost(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                const crow::Request&, const std::vector<std::string>&) override
-    {
-        clearDump(asyncResp, "System");
-    }
-};
-
-class CrashdumpService : public Node
-{
-  public:
-    CrashdumpService(App& app) :
-        Node(app, "/redfish/v1/Systems/system/LogServices/Crashdump/")
-    {
-        // Note: Deviated from redfish privilege registry for GET & HEAD
-        // method for security reasons.
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::head, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-    }
-
-  private:
-    /**
-     * Functions triggers appropriate requests on DBus
-     */
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&, const std::vector<std::string>&) override
-    {
-
-        // Copy over the static data to include the entries added by SubRoute
-        asyncResp->res.jsonValue["@odata.id"] =
-            "/redfish/v1/Systems/system/LogServices/Crashdump";
-        asyncResp->res.jsonValue["@odata.type"] =
-            "#LogService.v1_2_0.LogService";
-        asyncResp->res.jsonValue["Name"] = "Open BMC Oem Crashdump Service";
-        asyncResp->res.jsonValue["Description"] = "Oem Crashdump Service";
-        asyncResp->res.jsonValue["Id"] = "Oem Crashdump";
-        asyncResp->res.jsonValue["OverWritePolicy"] = "WrapsWhenFull";
-        asyncResp->res.jsonValue["MaxNumberOfRecords"] = 3;
-        asyncResp->res.jsonValue["Entries"] = {
-            {"@odata.id",
-             "/redfish/v1/Systems/system/LogServices/Crashdump/Entries"}};
-        asyncResp->res.jsonValue["Actions"] = {
-            {"#LogService.ClearLog",
-             {{"target", "/redfish/v1/Systems/system/LogServices/Crashdump/"
-                         "Actions/LogService.ClearLog"}}},
-            {"#LogService.CollectDiagnosticData",
-             {{"target", "/redfish/v1/Systems/system/LogServices/Crashdump/"
-                         "Actions/LogService.CollectDiagnosticData"}}}};
-    }
-};
-
-class CrashdumpClear : public Node
-{
-  public:
-    CrashdumpClear(App& app) :
-        Node(app, "/redfish/v1/Systems/system/LogServices/Crashdump/Actions/"
-                  "LogService.ClearLog/")
-    {
-        // Note: Deviated from redfish privilege registry for GET & HEAD
-        // method for security reasons.
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::head, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
-    }
-
-  private:
-    void doPost(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                const crow::Request&, const std::vector<std::string>&) override
-    {
-
-        crow::connections::systemBus->async_method_call(
-            [asyncResp](const boost::system::error_code ec,
-                        const std::string&) {
-                if (ec)
+                if (fillBMCJournalLogEntryJson(entryID, journal.get(),
+                                               asyncResp->res.jsonValue) != 0)
                 {
                     messages::internalError(asyncResp->res);
                     return;
                 }
-                messages::success(asyncResp->res);
-            },
-            crashdumpObject, crashdumpPath, deleteAllInterface, "DeleteAll");
-    }
-};
+            });
+}
+
+inline void requestRoutesBMCDumpService(App& app)
+{
+    BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/LogServices/Dump/")
+        .privileges({"Login"})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                asyncResp->res.jsonValue["@odata.id"] =
+                    "/redfish/v1/Managers/bmc/LogServices/Dump";
+                asyncResp->res.jsonValue["@odata.type"] =
+                    "#LogService.v1_2_0.LogService";
+                asyncResp->res.jsonValue["Name"] = "Dump LogService";
+                asyncResp->res.jsonValue["Description"] = "BMC Dump LogService";
+                asyncResp->res.jsonValue["Id"] = "Dump";
+                asyncResp->res.jsonValue["OverWritePolicy"] = "WrapsWhenFull";
+                asyncResp->res.jsonValue["Entries"] = {
+                    {"@odata.id",
+                     "/redfish/v1/Managers/bmc/LogServices/Dump/Entries"}};
+                asyncResp->res.jsonValue["Actions"] = {
+                    {"#LogService.ClearLog",
+                     {{"target", "/redfish/v1/Managers/bmc/LogServices/Dump/"
+                                 "Actions/LogService.ClearLog"}}},
+                    {"#LogService.CollectDiagnosticData",
+                     {{"target", "/redfish/v1/Managers/bmc/LogServices/Dump/"
+                                 "Actions/LogService.CollectDiagnosticData"}}}};
+            });
+}
+
+inline void requestRoutesBMCDumpEntryCollection(App& app)
+{
+
+    /**
+     * Functions triggers appropriate requests on DBus
+     */
+    BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/LogServices/Dump/Entries/")
+        .privileges({"Login"})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                asyncResp->res.jsonValue["@odata.type"] =
+                    "#LogEntryCollection.LogEntryCollection";
+                asyncResp->res.jsonValue["@odata.id"] =
+                    "/redfish/v1/Managers/bmc/LogServices/Dump/Entries";
+                asyncResp->res.jsonValue["Name"] = "BMC Dump Entries";
+                asyncResp->res.jsonValue["Description"] =
+                    "Collection of BMC Dump Entries";
+
+                getDumpEntryCollection(asyncResp, "BMC");
+            });
+}
+
+inline void requestRoutesBMCDumpEntry(App& app)
+{
+    BMCWEB_ROUTE(app,
+                 "/redfish/v1/Managers/bmc/LogServices/Dump/Entries/<str>/")
+        .privileges({"Login"})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+               const std::string& param) {
+                getDumpEntryById(asyncResp, param, "BMC");
+            });
+    BMCWEB_ROUTE(app,
+                 "/redfish/v1/Managers/bmc/LogServices/Dump/Entries/<str>/")
+        .privileges({"ConfigureManager"})
+        .methods(boost::beast::http::verb::delete_)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+               const std::string& param) {
+                deleteDumpEntry(asyncResp, param, "bmc");
+            });
+}
+
+inline void requestRoutesBMCDumpCreate(App& app)
+{
+
+    BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/LogServices/Dump/"
+                      "Actions/"
+                      "LogService.CollectDiagnosticData/")
+        .privileges({"ConfigureManager"})
+        .methods(boost::beast::http::verb::post)(
+            [](const crow::Request& req,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                createDump(asyncResp, req, "BMC");
+            });
+}
+
+inline void requestRoutesBMCDumpClear(App& app)
+{
+    BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/LogServices/Dump/"
+                      "Actions/"
+                      "LogService.ClearLog/")
+        .privileges({"ConfigureManager"})
+        .methods(boost::beast::http::verb::post)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                clearDump(asyncResp, "BMC");
+            });
+}
+
+inline void requestRoutesSystemDumpService(App& app)
+{
+    BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/LogServices/Dump/")
+        .privileges({"Login"})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+
+            {
+                asyncResp->res.jsonValue["@odata.id"] =
+                    "/redfish/v1/Systems/system/LogServices/Dump";
+                asyncResp->res.jsonValue["@odata.type"] =
+                    "#LogService.v1_2_0.LogService";
+                asyncResp->res.jsonValue["Name"] = "Dump LogService";
+                asyncResp->res.jsonValue["Description"] =
+                    "System Dump LogService";
+                asyncResp->res.jsonValue["Id"] = "Dump";
+                asyncResp->res.jsonValue["OverWritePolicy"] = "WrapsWhenFull";
+                asyncResp->res.jsonValue["Entries"] = {
+                    {"@odata.id",
+                     "/redfish/v1/Systems/system/LogServices/Dump/Entries"}};
+                asyncResp->res.jsonValue["Actions"] = {
+                    {"#LogService.ClearLog",
+                     {{"target",
+                       "/redfish/v1/Systems/system/LogServices/Dump/Actions/"
+                       "LogService.ClearLog"}}},
+                    {"#LogService.CollectDiagnosticData",
+                     {{"target",
+                       "/redfish/v1/Systems/system/LogServices/Dump/Actions/"
+                       "LogService.CollectDiagnosticData"}}}};
+            });
+}
+
+inline void requestRoutesSystemDumpEntryCollection(App& app)
+{
+
+    /**
+     * Functions triggers appropriate requests on DBus
+     */
+    BMCWEB_ROUTE(app,
+                 "/redfish/v1/Managers/bmc/LogServices/Dump/Entries/<str>/")
+        .privileges({"Login"})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+               const std::string&) {
+                asyncResp->res.jsonValue["@odata.type"] =
+                    "#LogEntryCollection.LogEntryCollection";
+                asyncResp->res.jsonValue["@odata.id"] =
+                    "/redfish/v1/Systems/system/LogServices/Dump/Entries";
+                asyncResp->res.jsonValue["Name"] = "System Dump Entries";
+                asyncResp->res.jsonValue["Description"] =
+                    "Collection of System Dump Entries";
+
+                getDumpEntryCollection(asyncResp, "System");
+            });
+}
+
+inline void requestRoutesSystemDumpEntry(App& app)
+{
+    BMCWEB_ROUTE(app,
+                 "redfish/v1/Systems/system/LogServices/Dump/Entries/<str>/")
+        .privileges({"Login"})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+               const std::string& param) {
+                getDumpEntryById(asyncResp, param, "System");
+            });
+
+    BMCWEB_ROUTE(app,
+                 "redfish/v1/Systems/system/LogServices/Dump/Entries/<str>/")
+        .privileges({"ConfigureManager"})
+        .methods(boost::beast::http::verb::delete_)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+               const std::string& param) {
+                deleteDumpEntry(asyncResp, param, "system");
+            });
+}
+
+inline void requestRoutesSystemDumpCreate(App& app)
+{
+    BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/LogServices/Dump/"
+                      "Actions/"
+                      "LogService.CollectDiagnosticData/")
+        .privileges({"ConfigureManager"})
+        .methods(boost::beast::http::verb::post)(
+            [](const crow::Request& req,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+
+            { createDump(asyncResp, req, "System"); });
+}
+
+inline void requestRoutesSystemDumpClear(App& app)
+{
+    BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/LogServices/Dump/"
+                      "Actions/"
+                      "LogService.ClearLog/")
+        .privileges({"ConfigureManager"})
+        .methods(boost::beast::http::verb::post)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+
+            { clearDump(asyncResp, "System"); });
+}
+
+inline void requestRoutesCrashdumpService(App& app)
+{
+    // Note: Deviated from redfish privilege registry for GET & HEAD
+    // method for security reasons.
+    /**
+     * Functions triggers appropriate requests on DBus
+     */
+    BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/LogServices/Crashdump/")
+        .privileges({"ConfigureManager"})
+        .methods(
+            boost::beast::http::verb::
+                get)([](const crow::Request&,
+                        const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+            // Copy over the static data to include the entries added by
+            // SubRoute
+            asyncResp->res.jsonValue["@odata.id"] =
+                "/redfish/v1/Systems/system/LogServices/Crashdump";
+            asyncResp->res.jsonValue["@odata.type"] =
+                "#LogService.v1_2_0.LogService";
+            asyncResp->res.jsonValue["Name"] = "Open BMC Oem Crashdump Service";
+            asyncResp->res.jsonValue["Description"] = "Oem Crashdump Service";
+            asyncResp->res.jsonValue["Id"] = "Oem Crashdump";
+            asyncResp->res.jsonValue["OverWritePolicy"] = "WrapsWhenFull";
+            asyncResp->res.jsonValue["MaxNumberOfRecords"] = 3;
+            asyncResp->res.jsonValue["Entries"] = {
+                {"@odata.id",
+                 "/redfish/v1/Systems/system/LogServices/Crashdump/Entries"}};
+            asyncResp->res.jsonValue["Actions"] = {
+                {"#LogService.ClearLog",
+                 {{"target", "/redfish/v1/Systems/system/LogServices/Crashdump/"
+                             "Actions/LogService.ClearLog"}}},
+                {"#LogService.CollectDiagnosticData",
+                 {{"target", "/redfish/v1/Systems/system/LogServices/Crashdump/"
+                             "Actions/LogService.CollectDiagnosticData"}}}};
+        });
+}
+
+void inline requestRoutesCrashdumpClear(App& app)
+{
+    BMCWEB_ROUTE(app,
+                 "/redfish/v1/Systems/system/LogServices/Crashdump/Actions/"
+                 "LogService.ClearLog/")
+        .privileges({"ConfigureComponents"})
+        .methods(boost::beast::http::verb::post)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                crow::connections::systemBus->async_method_call(
+                    [asyncResp](const boost::system::error_code ec,
+                                const std::string&) {
+                        if (ec)
+                        {
+                            messages::internalError(asyncResp->res);
+                            return;
+                        }
+                        messages::success(asyncResp->res);
+                    },
+                    crashdumpObject, crashdumpPath, deleteAllInterface,
+                    "DeleteAll");
+            });
+}
 
 static void
     logCrashdumpEntry(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
@@ -2690,474 +2395,396 @@
         "org.freedesktop.DBus.Properties", "GetAll", crashdumpInterface);
 }
 
-class CrashdumpEntryCollection : public Node
+inline void requestRoutesCrashdumpEntryCollection(App& app)
 {
-  public:
-    CrashdumpEntryCollection(App& app) :
-        Node(app, "/redfish/v1/Systems/system/LogServices/Crashdump/Entries/")
-    {
-        // Note: Deviated from redfish privilege registry for GET & HEAD
-        // method for security reasons.
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::head, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-    }
-
-  private:
+    // Note: Deviated from redfish privilege registry for GET & HEAD
+    // method for security reasons.
     /**
      * Functions triggers appropriate requests on DBus
      */
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&, const std::vector<std::string>&) override
-    {
-
-        // Collections don't include the static data added by SubRoute because
-        // it has a duplicate entry for members
-        auto getLogEntriesCallback = [asyncResp](
-                                         const boost::system::error_code ec,
-                                         const std::vector<std::string>& resp) {
-            if (ec)
-            {
-                if (ec.value() !=
-                    boost::system::errc::no_such_file_or_directory)
-                {
-                    BMCWEB_LOG_DEBUG << "failed to get entries ec: "
-                                     << ec.message();
-                    messages::internalError(asyncResp->res);
-                    return;
-                }
-            }
-            asyncResp->res.jsonValue["@odata.type"] =
-                "#LogEntryCollection.LogEntryCollection";
-            asyncResp->res.jsonValue["@odata.id"] =
-                "/redfish/v1/Systems/system/LogServices/Crashdump/Entries";
-            asyncResp->res.jsonValue["Name"] = "Open BMC Crashdump Entries";
-            asyncResp->res.jsonValue["Description"] =
-                "Collection of Crashdump Entries";
-            nlohmann::json& logEntryArray = asyncResp->res.jsonValue["Members"];
-            logEntryArray = nlohmann::json::array();
-            std::vector<std::string> logIDs;
-            // Get the list of log entries and build up an empty array big
-            // enough to hold them
-            for (const std::string& objpath : resp)
-            {
-                // Get the log ID
-                std::size_t lastPos = objpath.rfind('/');
-                if (lastPos == std::string::npos)
-                {
-                    continue;
-                }
-                logIDs.emplace_back(objpath.substr(lastPos + 1));
-
-                // Add a space for the log entry to the array
-                logEntryArray.push_back({});
-            }
-            // Now go through and set up async calls to fill in the entries
-            size_t index = 0;
-            for (const std::string& logID : logIDs)
-            {
-                // Add the log entry to the array
-                logCrashdumpEntry(asyncResp, logID, logEntryArray[index++]);
-            }
-            asyncResp->res.jsonValue["Members@odata.count"] =
-                logEntryArray.size();
-        };
-        crow::connections::systemBus->async_method_call(
-            std::move(getLogEntriesCallback),
-            "xyz.openbmc_project.ObjectMapper",
-            "/xyz/openbmc_project/object_mapper",
-            "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", "", 0,
-            std::array<const char*, 1>{crashdumpInterface});
-    }
-};
-
-class CrashdumpEntry : public Node
-{
-  public:
-    CrashdumpEntry(App& app) :
-        Node(app,
-             "/redfish/v1/Systems/system/LogServices/Crashdump/Entries/<str>/",
-             std::string())
-    {
-        // Note: Deviated from redfish privilege registry for GET & HEAD
-        // method for security reasons.
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::head, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-    }
-
-  private:
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&,
-               const std::vector<std::string>& params) override
-    {
-
-        if (params.size() != 1)
-        {
-            messages::internalError(asyncResp->res);
-            return;
-        }
-        const std::string& logID = params[0];
-        logCrashdumpEntry(asyncResp, logID, asyncResp->res.jsonValue);
-    }
-};
-
-class CrashdumpFile : public Node
-{
-  public:
-    CrashdumpFile(App& app) :
-        Node(app,
-             "/redfish/v1/Systems/system/LogServices/Crashdump/Entries/<str>/"
-             "<str>/",
-             std::string(), std::string())
-    {
-        // Note: Deviated from redfish privilege registry for GET & HEAD
-        // method for security reasons.
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::head, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-    }
-
-  private:
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&,
-               const std::vector<std::string>& params) override
-    {
-
-        if (params.size() != 2)
-        {
-            messages::internalError(asyncResp->res);
-            return;
-        }
-        const std::string& logID = params[0];
-        const std::string& fileName = params[1];
-
-        auto getStoredLogCallback =
-            [asyncResp, logID, fileName](
-                const boost::system::error_code ec,
-                const std::vector<std::pair<std::string, VariantType>>& resp) {
+    BMCWEB_ROUTE(app,
+                 "/redfish/v1/Systems/system/LogServices/Crashdump/Entries/")
+        .privileges({"ConfigureComponents"})
+        .methods(
+            boost::beast::http::verb::
+                get)([](const crow::Request&,
+                        const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+            // Collections don't include the static data added by SubRoute
+            // because it has a duplicate entry for members
+            auto getLogEntriesCallback = [asyncResp](
+                                             const boost::system::error_code ec,
+                                             const std::vector<std::string>&
+                                                 resp) {
                 if (ec)
                 {
-                    BMCWEB_LOG_DEBUG << "failed to get log ec: "
-                                     << ec.message();
-                    messages::internalError(asyncResp->res);
-                    return;
+                    if (ec.value() !=
+                        boost::system::errc::no_such_file_or_directory)
+                    {
+                        BMCWEB_LOG_DEBUG << "failed to get entries ec: "
+                                         << ec.message();
+                        messages::internalError(asyncResp->res);
+                        return;
+                    }
                 }
-
-                std::string dbusFilename{};
-                std::string dbusTimestamp{};
-                std::string dbusFilepath{};
-
-                parseCrashdumpParameters(resp, dbusFilename, dbusTimestamp,
-                                         dbusFilepath);
-
-                if (dbusFilename.empty() || dbusTimestamp.empty() ||
-                    dbusFilepath.empty())
+                asyncResp->res.jsonValue["@odata.type"] =
+                    "#LogEntryCollection.LogEntryCollection";
+                asyncResp->res.jsonValue["@odata.id"] =
+                    "/redfish/v1/Systems/system/LogServices/Crashdump/Entries";
+                asyncResp->res.jsonValue["Name"] = "Open BMC Crashdump Entries";
+                asyncResp->res.jsonValue["Description"] =
+                    "Collection of Crashdump Entries";
+                nlohmann::json& logEntryArray =
+                    asyncResp->res.jsonValue["Members"];
+                logEntryArray = nlohmann::json::array();
+                std::vector<std::string> logIDs;
+                // Get the list of log entries and build up an empty array big
+                // enough to hold them
+                for (const std::string& objpath : resp)
                 {
-                    messages::resourceMissingAtURI(asyncResp->res, fileName);
-                    return;
-                }
+                    // Get the log ID
+                    std::size_t lastPos = objpath.rfind('/');
+                    if (lastPos == std::string::npos)
+                    {
+                        continue;
+                    }
+                    logIDs.emplace_back(objpath.substr(lastPos + 1));
 
-                // Verify the file name parameter is correct
-                if (fileName != dbusFilename)
+                    // Add a space for the log entry to the array
+                    logEntryArray.push_back({});
+                }
+                // Now go through and set up async calls to fill in the entries
+                size_t index = 0;
+                for (const std::string& logID : logIDs)
                 {
-                    messages::resourceMissingAtURI(asyncResp->res, fileName);
-                    return;
+                    // Add the log entry to the array
+                    logCrashdumpEntry(asyncResp, logID, logEntryArray[index++]);
                 }
-
-                if (!std::filesystem::exists(dbusFilepath))
-                {
-                    messages::resourceMissingAtURI(asyncResp->res, fileName);
-                    return;
-                }
-                std::ifstream ifs(dbusFilepath, std::ios::in |
-                                                    std::ios::binary |
-                                                    std::ios::ate);
-                std::ifstream::pos_type fileSize = ifs.tellg();
-                if (fileSize < 0)
-                {
-                    messages::generalError(asyncResp->res);
-                    return;
-                }
-                ifs.seekg(0, std::ios::beg);
-
-                auto crashData = std::make_unique<char[]>(
-                    static_cast<unsigned int>(fileSize));
-
-                ifs.read(crashData.get(), static_cast<int>(fileSize));
-
-                // The cast to std::string is intentional in order to use the
-                // assign() that applies move mechanics
-                asyncResp->res.body().assign(
-                    static_cast<std::string>(crashData.get()));
-
-                // Configure this to be a file download when accessed from
-                // a browser
-                asyncResp->res.addHeader("Content-Disposition", "attachment");
+                asyncResp->res.jsonValue["Members@odata.count"] =
+                    logEntryArray.size();
             };
-        crow::connections::systemBus->async_method_call(
-            std::move(getStoredLogCallback), crashdumpObject,
-            crashdumpPath + std::string("/") + logID,
-            "org.freedesktop.DBus.Properties", "GetAll", crashdumpInterface);
-    }
-};
+            crow::connections::systemBus->async_method_call(
+                std::move(getLogEntriesCallback),
+                "xyz.openbmc_project.ObjectMapper",
+                "/xyz/openbmc_project/object_mapper",
+                "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", "", 0,
+                std::array<const char*, 1>{crashdumpInterface});
+        });
+}
 
-class CrashdumpCollect : public Node
+inline void requestRoutesCrashdumpEntry(App& app)
 {
-  public:
-    CrashdumpCollect(App& app) :
-        Node(app, "/redfish/v1/Systems/system/LogServices/Crashdump/Actions/"
-                  "LogService.CollectDiagnosticData/")
-    {
-        // Note: Deviated from redfish privilege registry for GET & HEAD
-        // method for security reasons.
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::head, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
-    }
+    // Note: Deviated from redfish privilege registry for GET & HEAD
+    // method for security reasons.
 
-  private:
-    void doPost(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                const crow::Request& req,
-                const std::vector<std::string>&) override
-    {
+    BMCWEB_ROUTE(
+        app, "/redfish/v1/Systems/system/LogServices/Crashdump/Entries/<str>/")
+        .privileges({"ConfigureComponents"})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+               const std::string& param) {
+                const std::string& logID = param;
+                logCrashdumpEntry(asyncResp, logID, asyncResp->res.jsonValue);
+            });
+}
 
-        std::string diagnosticDataType;
-        std::string oemDiagnosticDataType;
-        if (!redfish::json_util::readJson(
-                req, asyncResp->res, "DiagnosticDataType", diagnosticDataType,
-                "OEMDiagnosticDataType", oemDiagnosticDataType))
-        {
-            return;
-        }
+inline void requestRoutesCrashdumpFile(App& app)
+{
+    // Note: Deviated from redfish privilege registry for GET & HEAD
+    // method for security reasons.
+    BMCWEB_ROUTE(
+        app,
+        "/redfish/v1/Systems/system/LogServices/Crashdump/Entries/<str>/<str>/")
+        .privileges({"ConfigureComponents"})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+               const std::string& logID, const std::string& fileName) {
+                auto getStoredLogCallback =
+                    [asyncResp, logID, fileName](
+                        const boost::system::error_code ec,
+                        const std::vector<std::pair<std::string, VariantType>>&
+                            resp) {
+                        if (ec)
+                        {
+                            BMCWEB_LOG_DEBUG << "failed to get log ec: "
+                                             << ec.message();
+                            messages::internalError(asyncResp->res);
+                            return;
+                        }
 
-        if (diagnosticDataType != "OEM")
-        {
-            BMCWEB_LOG_ERROR
-                << "Only OEM DiagnosticDataType supported for Crashdump";
-            messages::actionParameterValueFormatError(
-                asyncResp->res, diagnosticDataType, "DiagnosticDataType",
-                "CollectDiagnosticData");
-            return;
-        }
+                        std::string dbusFilename{};
+                        std::string dbusTimestamp{};
+                        std::string dbusFilepath{};
 
-        auto collectCrashdumpCallback = [asyncResp, req](
-                                            const boost::system::error_code ec,
-                                            const std::string&) {
-            if (ec)
+                        parseCrashdumpParameters(resp, dbusFilename,
+                                                 dbusTimestamp, dbusFilepath);
+
+                        if (dbusFilename.empty() || dbusTimestamp.empty() ||
+                            dbusFilepath.empty())
+                        {
+                            messages::resourceMissingAtURI(asyncResp->res,
+                                                           fileName);
+                            return;
+                        }
+
+                        // Verify the file name parameter is correct
+                        if (fileName != dbusFilename)
+                        {
+                            messages::resourceMissingAtURI(asyncResp->res,
+                                                           fileName);
+                            return;
+                        }
+
+                        if (!std::filesystem::exists(dbusFilepath))
+                        {
+                            messages::resourceMissingAtURI(asyncResp->res,
+                                                           fileName);
+                            return;
+                        }
+                        std::ifstream ifs(dbusFilepath, std::ios::in |
+                                                            std::ios::binary |
+                                                            std::ios::ate);
+                        std::ifstream::pos_type fileSize = ifs.tellg();
+                        if (fileSize < 0)
+                        {
+                            messages::generalError(asyncResp->res);
+                            return;
+                        }
+                        ifs.seekg(0, std::ios::beg);
+
+                        auto crashData = std::make_unique<char[]>(
+                            static_cast<unsigned int>(fileSize));
+
+                        ifs.read(crashData.get(), static_cast<int>(fileSize));
+
+                        // The cast to std::string is intentional in order to
+                        // use the assign() that applies move mechanics
+                        asyncResp->res.body().assign(
+                            static_cast<std::string>(crashData.get()));
+
+                        // Configure this to be a file download when accessed
+                        // from a browser
+                        asyncResp->res.addHeader("Content-Disposition",
+                                                 "attachment");
+                    };
+                crow::connections::systemBus->async_method_call(
+                    std::move(getStoredLogCallback), crashdumpObject,
+                    crashdumpPath + std::string("/") + logID,
+                    "org.freedesktop.DBus.Properties", "GetAll",
+                    crashdumpInterface);
+            });
+}
+
+inline void requestRoutesCrashdumpCollect(App& app)
+{
+    // Note: Deviated from redfish privilege registry for GET & HEAD
+    // method for security reasons.
+    BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/LogServices/Crashdump/"
+                      "Actions/LogService.CollectDiagnosticData/")
+        .privileges({"ConfigureComponents"})
+        .methods(
+            boost::beast::http::verb::
+                post)([](const crow::Request& req,
+                         const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+            std::string diagnosticDataType;
+            std::string oemDiagnosticDataType;
+            if (!redfish::json_util::readJson(
+                    req, asyncResp->res, "DiagnosticDataType",
+                    diagnosticDataType, "OEMDiagnosticDataType",
+                    oemDiagnosticDataType))
             {
-                if (ec.value() == boost::system::errc::operation_not_supported)
-                {
-                    messages::resourceInStandby(asyncResp->res);
-                }
-                else if (ec.value() ==
-                         boost::system::errc::device_or_resource_busy)
-                {
-                    messages::serviceTemporarilyUnavailable(asyncResp->res,
-                                                            "60");
-                }
-                else
-                {
-                    messages::internalError(asyncResp->res);
-                }
                 return;
             }
-            std::shared_ptr<task::TaskData> task = task::TaskData::createTask(
-                [](boost::system::error_code err, sdbusplus::message::message&,
-                   const std::shared_ptr<task::TaskData>& taskData) {
-                    if (!err)
-                    {
-                        taskData->messages.emplace_back(
-                            messages::taskCompletedOK(
-                                std::to_string(taskData->index)));
-                        taskData->state = "Completed";
-                    }
-                    return task::completed;
-                },
-                "type='signal',interface='org.freedesktop.DBus.Properties',"
-                "member='PropertiesChanged',arg0namespace='com.intel."
-                "crashdump'");
-            task->startTimer(std::chrono::minutes(5));
-            task->populateResp(asyncResp->res);
-            task->payload.emplace(req);
-        };
 
-        if (oemDiagnosticDataType == "OnDemand")
-        {
-            crow::connections::systemBus->async_method_call(
-                std::move(collectCrashdumpCallback), crashdumpObject,
-                crashdumpPath, crashdumpOnDemandInterface,
-                "GenerateOnDemandLog");
-        }
-        else if (oemDiagnosticDataType == "Telemetry")
-        {
-            crow::connections::systemBus->async_method_call(
-                std::move(collectCrashdumpCallback), crashdumpObject,
-                crashdumpPath, crashdumpTelemetryInterface,
-                "GenerateTelemetryLog");
-        }
-        else
-        {
-            BMCWEB_LOG_ERROR << "Unsupported OEMDiagnosticDataType: "
-                             << oemDiagnosticDataType;
-            messages::actionParameterValueFormatError(
-                asyncResp->res, oemDiagnosticDataType, "OEMDiagnosticDataType",
-                "CollectDiagnosticData");
-            return;
-        }
-    }
-};
+            if (diagnosticDataType != "OEM")
+            {
+                BMCWEB_LOG_ERROR
+                    << "Only OEM DiagnosticDataType supported for Crashdump";
+                messages::actionParameterValueFormatError(
+                    asyncResp->res, diagnosticDataType, "DiagnosticDataType",
+                    "CollectDiagnosticData");
+                return;
+            }
+
+            auto collectCrashdumpCallback = [asyncResp, req](
+                                                const boost::system::error_code
+                                                    ec,
+                                                const std::string&) {
+                if (ec)
+                {
+                    if (ec.value() ==
+                        boost::system::errc::operation_not_supported)
+                    {
+                        messages::resourceInStandby(asyncResp->res);
+                    }
+                    else if (ec.value() ==
+                             boost::system::errc::device_or_resource_busy)
+                    {
+                        messages::serviceTemporarilyUnavailable(asyncResp->res,
+                                                                "60");
+                    }
+                    else
+                    {
+                        messages::internalError(asyncResp->res);
+                    }
+                    return;
+                }
+                std::shared_ptr<task::TaskData> task =
+                    task::TaskData::createTask(
+                        [](boost::system::error_code err,
+                           sdbusplus::message::message&,
+                           const std::shared_ptr<task::TaskData>& taskData) {
+                            if (!err)
+                            {
+                                taskData->messages.emplace_back(
+                                    messages::taskCompletedOK(
+                                        std::to_string(taskData->index)));
+                                taskData->state = "Completed";
+                            }
+                            return task::completed;
+                        },
+                        "type='signal',interface='org.freedesktop.DBus."
+                        "Properties',"
+                        "member='PropertiesChanged',arg0namespace='com.intel."
+                        "crashdump'");
+                task->startTimer(std::chrono::minutes(5));
+                task->populateResp(asyncResp->res);
+                task->payload.emplace(req);
+            };
+
+            if (oemDiagnosticDataType == "OnDemand")
+            {
+                crow::connections::systemBus->async_method_call(
+                    std::move(collectCrashdumpCallback), crashdumpObject,
+                    crashdumpPath, crashdumpOnDemandInterface,
+                    "GenerateOnDemandLog");
+            }
+            else if (oemDiagnosticDataType == "Telemetry")
+            {
+                crow::connections::systemBus->async_method_call(
+                    std::move(collectCrashdumpCallback), crashdumpObject,
+                    crashdumpPath, crashdumpTelemetryInterface,
+                    "GenerateTelemetryLog");
+            }
+            else
+            {
+                BMCWEB_LOG_ERROR << "Unsupported OEMDiagnosticDataType: "
+                                 << oemDiagnosticDataType;
+                messages::actionParameterValueFormatError(
+                    asyncResp->res, oemDiagnosticDataType,
+                    "OEMDiagnosticDataType", "CollectDiagnosticData");
+                return;
+            }
+        });
+}
 
 /**
  * DBusLogServiceActionsClear class supports POST method for ClearLog action.
  */
-class DBusLogServiceActionsClear : public Node
+inline void requestRoutesDBusLogServiceActionsClear(App& app)
 {
-  public:
-    DBusLogServiceActionsClear(App& app) :
-        Node(app, "/redfish/v1/Systems/system/LogServices/EventLog/Actions/"
-                  "LogService.ClearLog/")
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-    }
-
-  private:
     /**
      * Function handles POST method request.
      * The Clear Log actions does not require any parameter.The action deletes
      * all entries found in the Entries collection for this Log Service.
      */
-    void doPost(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                const crow::Request&, const std::vector<std::string>&) override
-    {
-        BMCWEB_LOG_DEBUG << "Do delete all entries.";
 
-        // Process response from Logging service.
-        auto respHandler = [asyncResp](const boost::system::error_code ec) {
-            BMCWEB_LOG_DEBUG << "doClearLog resp_handler callback: Done";
-            if (ec)
-            {
-                // TODO Handle for specific error code
-                BMCWEB_LOG_ERROR << "doClearLog resp_handler got error " << ec;
-                asyncResp->res.result(
-                    boost::beast::http::status::internal_server_error);
-                return;
-            }
+    BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/LogServices/EventLog/Actions/"
+                      "LogService.ClearLog/")
+        .privileges({"ConfigureManager"})
+        .methods(boost::beast::http::verb::post)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                BMCWEB_LOG_DEBUG << "Do delete all entries.";
 
-            asyncResp->res.result(boost::beast::http::status::no_content);
-        };
+                // Process response from Logging service.
+                auto respHandler = [asyncResp](
+                                       const boost::system::error_code ec) {
+                    BMCWEB_LOG_DEBUG
+                        << "doClearLog resp_handler callback: Done";
+                    if (ec)
+                    {
+                        // TODO Handle for specific error code
+                        BMCWEB_LOG_ERROR << "doClearLog resp_handler got error "
+                                         << ec;
+                        asyncResp->res.result(
+                            boost::beast::http::status::internal_server_error);
+                        return;
+                    }
 
-        // Make call to Logging service to request Clear Log
-        crow::connections::systemBus->async_method_call(
-            respHandler, "xyz.openbmc_project.Logging",
-            "/xyz/openbmc_project/logging",
-            "xyz.openbmc_project.Collection.DeleteAll", "DeleteAll");
-    }
-};
+                    asyncResp->res.result(
+                        boost::beast::http::status::no_content);
+                };
+
+                // Make call to Logging service to request Clear Log
+                crow::connections::systemBus->async_method_call(
+                    respHandler, "xyz.openbmc_project.Logging",
+                    "/xyz/openbmc_project/logging",
+                    "xyz.openbmc_project.Collection.DeleteAll", "DeleteAll");
+            });
+}
 
 /****************************************************
  * Redfish PostCode interfaces
  * using DBUS interface: getPostCodesTS
  ******************************************************/
-class PostCodesLogService : public Node
+inline void requestRoutesPostCodesLogService(App& app)
 {
-  public:
-    PostCodesLogService(App& app) :
-        Node(app, "/redfish/v1/Systems/system/LogServices/PostCodes/")
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-    }
+    BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/LogServices/PostCodes/")
+        .privileges({"Login"})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                asyncResp->res.jsonValue = {
+                    {"@odata.id",
+                     "/redfish/v1/Systems/system/LogServices/PostCodes"},
+                    {"@odata.type", "#LogService.v1_1_0.LogService"},
+                    {"Name", "POST Code Log Service"},
+                    {"Description", "POST Code Log Service"},
+                    {"Id", "BIOS POST Code Log"},
+                    {"OverWritePolicy", "WrapsWhenFull"},
+                    {"Entries",
+                     {{"@odata.id", "/redfish/v1/Systems/system/LogServices/"
+                                    "PostCodes/Entries"}}}};
+                asyncResp->res.jsonValue["Actions"]["#LogService.ClearLog"] = {
+                    {"target",
+                     "/redfish/v1/Systems/system/LogServices/PostCodes/"
+                     "Actions/LogService.ClearLog"}};
+            });
+}
 
-  private:
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&, const std::vector<std::string>&) override
-    {
-
-        asyncResp->res.jsonValue = {
-            {"@odata.id", "/redfish/v1/Systems/system/LogServices/PostCodes"},
-            {"@odata.type", "#LogService.v1_1_0.LogService"},
-            {"Name", "POST Code Log Service"},
-            {"Description", "POST Code Log Service"},
-            {"Id", "BIOS POST Code Log"},
-            {"OverWritePolicy", "WrapsWhenFull"},
-            {"Entries",
-             {{"@odata.id",
-               "/redfish/v1/Systems/system/LogServices/PostCodes/Entries"}}}};
-        asyncResp->res.jsonValue["Actions"]["#LogService.ClearLog"] = {
-            {"target", "/redfish/v1/Systems/system/LogServices/PostCodes/"
-                       "Actions/LogService.ClearLog"}};
-    }
-};
-
-class PostCodesClear : public Node
+inline void requestRoutesPostCodesClear(App& app)
 {
-  public:
-    PostCodesClear(App& app) :
-        Node(app, "/redfish/v1/Systems/system/LogServices/PostCodes/Actions/"
-                  "LogService.ClearLog/")
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
-    }
+    BMCWEB_ROUTE(app,
+                 "/redfish/v1/Systems/system/LogServices/PostCodes/Actions/"
+                 "LogService.ClearLog/")
+        .privileges({"ConfigureComponents"})
+        .methods(boost::beast::http::verb::post)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                BMCWEB_LOG_DEBUG << "Do delete all postcodes entries.";
 
-  private:
-    void doPost(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                const crow::Request&, const std::vector<std::string>&) override
-    {
-        BMCWEB_LOG_DEBUG << "Do delete all postcodes entries.";
-
-        // Make call to post-code service to request clear all
-        crow::connections::systemBus->async_method_call(
-            [asyncResp](const boost::system::error_code ec) {
-                if (ec)
-                {
-                    // TODO Handle for specific error code
-                    BMCWEB_LOG_ERROR
-                        << "doClearPostCodes resp_handler got error " << ec;
-                    asyncResp->res.result(
-                        boost::beast::http::status::internal_server_error);
-                    messages::internalError(asyncResp->res);
-                    return;
-                }
-            },
-            "xyz.openbmc_project.State.Boot.PostCode0",
-            "/xyz/openbmc_project/State/Boot/PostCode0",
-            "xyz.openbmc_project.Collection.DeleteAll", "DeleteAll");
-    }
-};
+                // Make call to post-code service to request clear all
+                crow::connections::systemBus->async_method_call(
+                    [asyncResp](const boost::system::error_code ec) {
+                        if (ec)
+                        {
+                            // TODO Handle for specific error code
+                            BMCWEB_LOG_ERROR
+                                << "doClearPostCodes resp_handler got error "
+                                << ec;
+                            asyncResp->res.result(boost::beast::http::status::
+                                                      internal_server_error);
+                            messages::internalError(asyncResp->res);
+                            return;
+                        }
+                    },
+                    "xyz.openbmc_project.State.Boot.PostCode0",
+                    "/xyz/openbmc_project/State/Boot/PostCode0",
+                    "xyz.openbmc_project.Collection.DeleteAll", "DeleteAll");
+            });
+}
 
 static void fillPostCodeEntry(
     const std::shared_ptr<bmcweb::AsyncResp>& aResp,
@@ -3400,124 +3027,91 @@
         "xyz.openbmc_project.State.Boot.PostCode", "CurrentBootCycleCount");
 }
 
-class PostCodesEntryCollection : public Node
+inline void requestRoutesPostCodesEntryCollection(App& app)
 {
-  public:
-    PostCodesEntryCollection(App& app) :
-        Node(app, "/redfish/v1/Systems/system/LogServices/PostCodes/Entries/")
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-    }
+    BMCWEB_ROUTE(app,
+                 "/redfish/v1/Systems/system/LogServices/PostCodes/Entries/")
+        .privileges({"Login"})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request& req,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                asyncResp->res.jsonValue["@odata.type"] =
+                    "#LogEntryCollection.LogEntryCollection";
+                asyncResp->res.jsonValue["@odata.id"] =
+                    "/redfish/v1/Systems/system/LogServices/PostCodes/Entries";
+                asyncResp->res.jsonValue["Name"] = "BIOS POST Code Log Entries";
+                asyncResp->res.jsonValue["Description"] =
+                    "Collection of POST Code Log Entries";
+                asyncResp->res.jsonValue["Members"] = nlohmann::json::array();
+                asyncResp->res.jsonValue["Members@odata.count"] = 0;
 
-  private:
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request& req,
-               const std::vector<std::string>&) override
-    {
+                uint64_t skip = 0;
+                uint64_t top = maxEntriesPerPage; // Show max entries by default
+                if (!getSkipParam(asyncResp, req, skip))
+                {
+                    return;
+                }
+                if (!getTopParam(asyncResp, req, top))
+                {
+                    return;
+                }
+                getCurrentBootNumber(asyncResp, skip, top);
+            });
+}
 
-        asyncResp->res.jsonValue["@odata.type"] =
-            "#LogEntryCollection.LogEntryCollection";
-        asyncResp->res.jsonValue["@odata.id"] =
-            "/redfish/v1/Systems/system/LogServices/PostCodes/Entries";
-        asyncResp->res.jsonValue["Name"] = "BIOS POST Code Log Entries";
-        asyncResp->res.jsonValue["Description"] =
-            "Collection of POST Code Log Entries";
-        asyncResp->res.jsonValue["Members"] = nlohmann::json::array();
-        asyncResp->res.jsonValue["Members@odata.count"] = 0;
-
-        uint64_t skip = 0;
-        uint64_t top = maxEntriesPerPage; // Show max entries by default
-        if (!getSkipParam(asyncResp, req, skip))
-        {
-            return;
-        }
-        if (!getTopParam(asyncResp, req, top))
-        {
-            return;
-        }
-        getCurrentBootNumber(asyncResp, skip, top);
-    }
-};
-
-class PostCodesEntry : public Node
+inline void requestRoutesPostCodesEntry(App& app)
 {
-  public:
-    PostCodesEntry(App& app) :
-        Node(app,
-             "/redfish/v1/Systems/system/LogServices/PostCodes/Entries/<str>/",
-             std::string())
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-    }
+    BMCWEB_ROUTE(
+        app, "/redfish/v1/Systems/system/LogServices/PostCodes/Entries/<str>/")
+        .privileges({"Login"})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+               const std::string& targetID) {
+                size_t bootPos = targetID.find('B');
+                if (bootPos == std::string::npos)
+                {
+                    // Requested ID was not found
+                    messages::resourceMissingAtURI(asyncResp->res, targetID);
+                    return;
+                }
+                std::string_view bootIndexStr(targetID);
+                bootIndexStr.remove_prefix(bootPos + 1);
+                uint16_t bootIndex = 0;
+                uint64_t codeIndex = 0;
+                size_t dashPos = bootIndexStr.find('-');
 
-  private:
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&,
-               const std::vector<std::string>& params) override
-    {
+                if (dashPos == std::string::npos)
+                {
+                    return;
+                }
+                std::string_view codeIndexStr(bootIndexStr);
+                bootIndexStr.remove_suffix(dashPos);
+                codeIndexStr.remove_prefix(dashPos + 1);
 
-        if (params.size() != 1)
-        {
-            messages::internalError(asyncResp->res);
-            return;
-        }
+                bootIndex = static_cast<uint16_t>(
+                    strtoul(std::string(bootIndexStr).c_str(), nullptr, 0));
+                codeIndex =
+                    strtoul(std::string(codeIndexStr).c_str(), nullptr, 0);
+                if (bootIndex == 0 || codeIndex == 0)
+                {
+                    BMCWEB_LOG_DEBUG << "Get Post Code invalid entry string "
+                                     << targetID;
+                }
 
-        const std::string& targetID = params[0];
+                asyncResp->res.jsonValue["@odata.type"] =
+                    "#LogEntry.v1_4_0.LogEntry";
+                asyncResp->res.jsonValue["@odata.id"] =
+                    "/redfish/v1/Systems/system/LogServices/PostCodes/"
+                    "Entries";
+                asyncResp->res.jsonValue["Name"] = "BIOS POST Code Log Entries";
+                asyncResp->res.jsonValue["Description"] =
+                    "Collection of POST Code Log Entries";
+                asyncResp->res.jsonValue["Members"] = nlohmann::json::array();
+                asyncResp->res.jsonValue["Members@odata.count"] = 0;
 
-        size_t bootPos = targetID.find('B');
-        if (bootPos == std::string::npos)
-        {
-            // Requested ID was not found
-            messages::resourceMissingAtURI(asyncResp->res, targetID);
-            return;
-        }
-        std::string_view bootIndexStr(targetID);
-        bootIndexStr.remove_prefix(bootPos + 1);
-        uint16_t bootIndex = 0;
-        uint64_t codeIndex = 0;
-        size_t dashPos = bootIndexStr.find('-');
-
-        if (dashPos == std::string::npos)
-        {
-            return;
-        }
-        std::string_view codeIndexStr(bootIndexStr);
-        bootIndexStr.remove_suffix(dashPos);
-        codeIndexStr.remove_prefix(dashPos + 1);
-
-        bootIndex = static_cast<uint16_t>(
-            strtoul(std::string(bootIndexStr).c_str(), nullptr, 0));
-        codeIndex = strtoul(std::string(codeIndexStr).c_str(), nullptr, 0);
-        if (bootIndex == 0 || codeIndex == 0)
-        {
-            BMCWEB_LOG_DEBUG << "Get Post Code invalid entry string "
-                             << params[0];
-        }
-
-        asyncResp->res.jsonValue["@odata.type"] = "#LogEntry.v1_4_0.LogEntry";
-        asyncResp->res.jsonValue["@odata.id"] =
-            "/redfish/v1/Systems/system/LogServices/PostCodes/"
-            "Entries";
-        asyncResp->res.jsonValue["Name"] = "BIOS POST Code Log Entries";
-        asyncResp->res.jsonValue["Description"] =
-            "Collection of POST Code Log Entries";
-        asyncResp->res.jsonValue["Members"] = nlohmann::json::array();
-        asyncResp->res.jsonValue["Members@odata.count"] = 0;
-
-        getPostCodeForEntry(asyncResp, bootIndex, codeIndex);
-    }
-};
+                getPostCodeForEntry(asyncResp, bootIndex, codeIndex);
+            });
+}
 
 } // namespace redfish
diff --git a/redfish-core/lib/managers.hpp b/redfish-core/lib/managers.hpp
index 67f8d99..a92f490 100644
--- a/redfish-core/lib/managers.hpp
+++ b/redfish-core/lib/managers.hpp
@@ -16,9 +16,9 @@
 #pragma once
 
 #include "health.hpp"
-#include "node.hpp"
 #include "redfish_util.hpp"
 
+#include <app.hpp>
 #include <boost/algorithm/string/replace.hpp>
 #include <boost/date_time.hpp>
 #include <dbus_utility.hpp>
@@ -100,71 +100,57 @@
  * ManagerResetAction class supports the POST method for the Reset (reboot)
  * action.
  */
-class ManagerResetAction : public Node
+inline void requestRoutesManagerResetAction(App& app)
 {
-  public:
-    ManagerResetAction(App& app) :
-        Node(app, "/redfish/v1/Managers/bmc/Actions/Manager.Reset/")
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-    }
-
-  private:
     /**
      * Function handles POST method request.
      * Analyzes POST body before sending Reset (Reboot) request data to D-Bus.
      * OpenBMC supports ResetType "GracefulRestart" and "ForceRestart".
      */
-    void doPost(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                const crow::Request& req,
-                const std::vector<std::string>&) override
-    {
-        BMCWEB_LOG_DEBUG << "Post Manager Reset.";
 
-        std::string resetType;
+    BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/Actions/Manager.Reset/")
+        .privileges({"ConfigureManager"})
+        .methods(boost::beast::http::verb::post)(
+            [](const crow::Request& req,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                BMCWEB_LOG_DEBUG << "Post Manager Reset.";
 
-        if (!json_util::readJson(req, asyncResp->res, "ResetType", resetType))
-        {
-            return;
-        }
+                std::string resetType;
 
-        if (resetType == "GracefulRestart")
-        {
-            BMCWEB_LOG_DEBUG << "Proceeding with " << resetType;
-            doBMCGracefulRestart(asyncResp);
-            return;
-        }
-        if (resetType == "ForceRestart")
-        {
-            BMCWEB_LOG_DEBUG << "Proceeding with " << resetType;
-            doBMCForceRestart(asyncResp);
-            return;
-        }
-        BMCWEB_LOG_DEBUG << "Invalid property value for ResetType: "
-                         << resetType;
-        messages::actionParameterNotSupported(asyncResp->res, resetType,
-                                              "ResetType");
+                if (!json_util::readJson(req, asyncResp->res, "ResetType",
+                                         resetType))
+                {
+                    return;
+                }
 
-        return;
-    }
-};
+                if (resetType == "GracefulRestart")
+                {
+                    BMCWEB_LOG_DEBUG << "Proceeding with " << resetType;
+                    doBMCGracefulRestart(asyncResp);
+                    return;
+                }
+                if (resetType == "ForceRestart")
+                {
+                    BMCWEB_LOG_DEBUG << "Proceeding with " << resetType;
+                    doBMCForceRestart(asyncResp);
+                    return;
+                }
+                BMCWEB_LOG_DEBUG << "Invalid property value for ResetType: "
+                                 << resetType;
+                messages::actionParameterNotSupported(asyncResp->res, resetType,
+                                                      "ResetType");
+
+                return;
+            });
+}
 
 /**
  * ManagerResetToDefaultsAction class supports POST method for factory reset
  * action.
  */
-class ManagerResetToDefaultsAction : public Node
+inline void requestRoutesManagerResetToDefaultsAction(App& app)
 {
-  public:
-    ManagerResetToDefaultsAction(App& app) :
-        Node(app, "/redfish/v1/Managers/bmc/Actions/Manager.ResetToDefaults/")
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-    }
 
-  private:
     /**
      * Function handles ResetToDefaults POST method request.
      *
@@ -176,93 +162,85 @@
      *
      * OpenBMC only supports ResetToDefaultsType "ResetAll".
      */
-    void doPost(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                const crow::Request& req,
-                const std::vector<std::string>&) override
-    {
-        BMCWEB_LOG_DEBUG << "Post ResetToDefaults.";
 
-        std::string resetType;
+    BMCWEB_ROUTE(app,
+                 "/redfish/v1/Managers/bmc/Actions/Manager.ResetToDefaults/")
+        .privileges({"ConfigureManager"})
+        .methods(boost::beast::http::verb::post)(
+            [](const crow::Request& req,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                BMCWEB_LOG_DEBUG << "Post ResetToDefaults.";
 
-        if (!json_util::readJson(req, asyncResp->res, "ResetToDefaultsType",
-                                 resetType))
-        {
-            BMCWEB_LOG_DEBUG << "Missing property ResetToDefaultsType.";
+                std::string resetType;
 
-            messages::actionParameterMissing(asyncResp->res, "ResetToDefaults",
-                                             "ResetToDefaultsType");
-            return;
-        }
-
-        if (resetType != "ResetAll")
-        {
-            BMCWEB_LOG_DEBUG << "Invalid property value for "
-                                "ResetToDefaultsType: "
-                             << resetType;
-            messages::actionParameterNotSupported(asyncResp->res, resetType,
-                                                  "ResetToDefaultsType");
-            return;
-        }
-
-        crow::connections::systemBus->async_method_call(
-            [asyncResp](const boost::system::error_code ec) {
-                if (ec)
+                if (!json_util::readJson(req, asyncResp->res,
+                                         "ResetToDefaultsType", resetType))
                 {
-                    BMCWEB_LOG_DEBUG << "Failed to ResetToDefaults: " << ec;
-                    messages::internalError(asyncResp->res);
+                    BMCWEB_LOG_DEBUG << "Missing property ResetToDefaultsType.";
+
+                    messages::actionParameterMissing(asyncResp->res,
+                                                     "ResetToDefaults",
+                                                     "ResetToDefaultsType");
                     return;
                 }
-                // Factory Reset doesn't actually happen until a reboot
-                // Can't erase what the BMC is running on
-                doBMCGracefulRestart(asyncResp);
-            },
-            "xyz.openbmc_project.Software.BMC.Updater",
-            "/xyz/openbmc_project/software",
-            "xyz.openbmc_project.Common.FactoryReset", "Reset");
-    }
-};
+
+                if (resetType != "ResetAll")
+                {
+                    BMCWEB_LOG_DEBUG << "Invalid property value for "
+                                        "ResetToDefaultsType: "
+                                     << resetType;
+                    messages::actionParameterNotSupported(
+                        asyncResp->res, resetType, "ResetToDefaultsType");
+                    return;
+                }
+
+                crow::connections::systemBus->async_method_call(
+                    [asyncResp](const boost::system::error_code ec) {
+                        if (ec)
+                        {
+                            BMCWEB_LOG_DEBUG << "Failed to ResetToDefaults: "
+                                             << ec;
+                            messages::internalError(asyncResp->res);
+                            return;
+                        }
+                        // Factory Reset doesn't actually happen until a reboot
+                        // Can't erase what the BMC is running on
+                        doBMCGracefulRestart(asyncResp);
+                    },
+                    "xyz.openbmc_project.Software.BMC.Updater",
+                    "/xyz/openbmc_project/software",
+                    "xyz.openbmc_project.Common.FactoryReset", "Reset");
+            });
+}
 
 /**
  * ManagerResetActionInfo derived class for delivering Manager
  * ResetType AllowableValues using ResetInfo schema.
  */
-class ManagerResetActionInfo : public Node
+inline void requestRoutesManagerResetActionInfo(App& app)
 {
-  public:
-    /*
-     * Default Constructor
-     */
-    ManagerResetActionInfo(App& app) :
-        Node(app, "/redfish/v1/Managers/bmc/ResetActionInfo/")
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
-    }
-
-  private:
     /**
      * Functions triggers appropriate requests on DBus
      */
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&, const std::vector<std::string>&) override
-    {
-        asyncResp->res.jsonValue = {
-            {"@odata.type", "#ActionInfo.v1_1_2.ActionInfo"},
-            {"@odata.id", "/redfish/v1/Managers/bmc/ResetActionInfo"},
-            {"Name", "Reset Action Info"},
-            {"Id", "ResetActionInfo"},
-            {"Parameters",
-             {{{"Name", "ResetType"},
-               {"Required", true},
-               {"DataType", "String"},
-               {"AllowableValues", {"GracefulRestart", "ForceRestart"}}}}}};
-    }
-};
+
+    BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/ResetActionInfo/")
+        .privileges({"Login"})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                asyncResp->res.jsonValue = {
+                    {"@odata.type", "#ActionInfo.v1_1_2.ActionInfo"},
+                    {"@odata.id", "/redfish/v1/Managers/bmc/ResetActionInfo"},
+                    {"Name", "Reset Action Info"},
+                    {"Id", "ResetActionInfo"},
+                    {"Parameters",
+                     {{{"Name", "ResetType"},
+                       {"Required", true},
+                       {"DataType", "String"},
+                       {"AllowableValues",
+                        {"GracefulRestart", "ForceRestart"}}}}}};
+            });
+}
 
 static constexpr const char* objectManagerIface =
     "org.freedesktop.DBus.ObjectManager";
@@ -1746,561 +1724,557 @@
         "LocationCode",
         "LocationCode");
 }
-
-class Manager : public Node
+// avoid name collision systems.hpp
+inline void
+    managerGetLastResetTime(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
 {
-  public:
-    Manager(App& app) : Node(app, "/redfish/v1/Managers/bmc/")
-    {
+    BMCWEB_LOG_DEBUG << "Getting Manager Last Reset Time";
 
-        uuid = persistent_data::getConfig().systemUuid;
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-    }
-
-  private:
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&, const std::vector<std::string>&) override
-    {
-        asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Managers/bmc";
-        asyncResp->res.jsonValue["@odata.type"] = "#Manager.v1_11_0.Manager";
-        asyncResp->res.jsonValue["Id"] = "bmc";
-        asyncResp->res.jsonValue["Name"] = "OpenBmc Manager";
-        asyncResp->res.jsonValue["Description"] =
-            "Baseboard Management Controller";
-        asyncResp->res.jsonValue["PowerState"] = "On";
-        asyncResp->res.jsonValue["Status"] = {{"State", "Enabled"},
-                                              {"Health", "OK"}};
-        asyncResp->res.jsonValue["ManagerType"] = "BMC";
-        asyncResp->res.jsonValue["UUID"] = systemd_utils::getUuid();
-        asyncResp->res.jsonValue["ServiceEntryPointUUID"] = uuid;
-        asyncResp->res.jsonValue["Model"] = "OpenBmc"; // TODO(ed), get model
-
-        asyncResp->res.jsonValue["LogServices"] = {
-            {"@odata.id", "/redfish/v1/Managers/bmc/LogServices"}};
-
-        asyncResp->res.jsonValue["NetworkProtocol"] = {
-            {"@odata.id", "/redfish/v1/Managers/bmc/NetworkProtocol"}};
-
-        asyncResp->res.jsonValue["EthernetInterfaces"] = {
-            {"@odata.id", "/redfish/v1/Managers/bmc/EthernetInterfaces"}};
-
-#ifdef BMCWEB_ENABLE_VM_NBDPROXY
-        asyncResp->res.jsonValue["VirtualMedia"] = {
-            {"@odata.id", "/redfish/v1/Managers/bmc/VirtualMedia"}};
-#endif // BMCWEB_ENABLE_VM_NBDPROXY
-
-        // default oem data
-        nlohmann::json& oem = asyncResp->res.jsonValue["Oem"];
-        nlohmann::json& oemOpenbmc = oem["OpenBmc"];
-        oem["@odata.type"] = "#OemManager.Oem";
-        oem["@odata.id"] = "/redfish/v1/Managers/bmc#/Oem";
-        oemOpenbmc["@odata.type"] = "#OemManager.OpenBmc";
-        oemOpenbmc["@odata.id"] = "/redfish/v1/Managers/bmc#/Oem/OpenBmc";
-        oemOpenbmc["Certificates"] = {
-            {"@odata.id", "/redfish/v1/Managers/bmc/Truststore/Certificates"}};
-
-        // Manager.Reset (an action) can be many values, OpenBMC only supports
-        // BMC reboot.
-        nlohmann::json& managerReset =
-            asyncResp->res.jsonValue["Actions"]["#Manager.Reset"];
-        managerReset["target"] =
-            "/redfish/v1/Managers/bmc/Actions/Manager.Reset";
-        managerReset["@Redfish.ActionInfo"] =
-            "/redfish/v1/Managers/bmc/ResetActionInfo";
-
-        // ResetToDefaults (Factory Reset) has values like
-        // PreserveNetworkAndUsers and PreserveNetwork that aren't supported
-        // on OpenBMC
-        nlohmann::json& resetToDefaults =
-            asyncResp->res.jsonValue["Actions"]["#Manager.ResetToDefaults"];
-        resetToDefaults["target"] =
-            "/redfish/v1/Managers/bmc/Actions/Manager.ResetToDefaults";
-        resetToDefaults["ResetType@Redfish.AllowableValues"] = {"ResetAll"};
-
-        asyncResp->res.jsonValue["DateTime"] = crow::utility::dateTimeNow();
-
-        // Fill in SerialConsole info
-        asyncResp->res.jsonValue["SerialConsole"]["ServiceEnabled"] = true;
-        asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] = 15;
-        asyncResp->res.jsonValue["SerialConsole"]["ConnectTypesSupported"] = {
-            "IPMI", "SSH"};
-#ifdef BMCWEB_ENABLE_KVM
-        // Fill in GraphicalConsole info
-        asyncResp->res.jsonValue["GraphicalConsole"]["ServiceEnabled"] = true;
-        asyncResp->res.jsonValue["GraphicalConsole"]["MaxConcurrentSessions"] =
-            4;
-        asyncResp->res
-            .jsonValue["GraphicalConsole"]["ConnectTypesSupported"] = {"KVMIP"};
-#endif // BMCWEB_ENABLE_KVM
-
-        asyncResp->res.jsonValue["Links"]["ManagerForServers@odata.count"] = 1;
-        asyncResp->res.jsonValue["Links"]["ManagerForServers"] = {
-            {{"@odata.id", "/redfish/v1/Systems/system"}}};
-
-        auto health = std::make_shared<HealthPopulate>(asyncResp);
-        health->isManagersHealth = true;
-        health->populate();
-
-        fw_util::populateFirmwareInformation(asyncResp, fw_util::bmcPurpose,
-                                             "FirmwareVersion", true);
-
-        getLastResetTime(asyncResp);
-
-        auto pids = std::make_shared<GetPIDValues>(asyncResp);
-        pids->run();
-
-        getMainChassisId(
-            asyncResp, [](const std::string& chassisId,
-                          const std::shared_ptr<bmcweb::AsyncResp>& aRsp) {
-                aRsp->res.jsonValue["Links"]["ManagerForChassis@odata.count"] =
-                    1;
-                aRsp->res.jsonValue["Links"]["ManagerForChassis"] = {
-                    {{"@odata.id", "/redfish/v1/Chassis/" + chassisId}}};
-                aRsp->res.jsonValue["Links"]["ManagerInChassis"] = {
-                    {"@odata.id", "/redfish/v1/Chassis/" + chassisId}};
-            });
-
-        static bool started = false;
-
-        if (!started)
-        {
-            crow::connections::systemBus->async_method_call(
-                [asyncResp](const boost::system::error_code ec,
-                            const std::variant<double>& resp) {
-                    if (ec)
-                    {
-                        BMCWEB_LOG_ERROR << "Error while getting progress";
-                        messages::internalError(asyncResp->res);
-                        return;
-                    }
-                    const double* val = std::get_if<double>(&resp);
-                    if (val == nullptr)
-                    {
-                        BMCWEB_LOG_ERROR
-                            << "Invalid response while getting progress";
-                        messages::internalError(asyncResp->res);
-                        return;
-                    }
-                    if (*val < 1.0)
-                    {
-                        asyncResp->res.jsonValue["Status"]["State"] =
-                            "Starting";
-                        started = true;
-                    }
-                },
-                "org.freedesktop.systemd1", "/org/freedesktop/systemd1",
-                "org.freedesktop.DBus.Properties", "Get",
-                "org.freedesktop.systemd1.Manager", "Progress");
-        }
-
-        crow::connections::systemBus->async_method_call(
-            [asyncResp](
-                const boost::system::error_code ec,
-                const std::vector<std::pair<
-                    std::string, std::vector<std::pair<
-                                     std::string, std::vector<std::string>>>>>&
-                    subtree) {
-                if (ec)
-                {
-                    BMCWEB_LOG_DEBUG << "D-Bus response error on GetSubTree "
-                                     << ec;
-                    return;
-                }
-                if (subtree.size() == 0)
-                {
-                    BMCWEB_LOG_DEBUG << "Can't find bmc D-Bus object!";
-                    return;
-                }
-                // Assume only 1 bmc D-Bus object
-                // Throw an error if there is more than 1
-                if (subtree.size() > 1)
-                {
-                    BMCWEB_LOG_DEBUG << "Found more than 1 bmc D-Bus object!";
-                    messages::internalError(asyncResp->res);
-                    return;
-                }
-
-                if (subtree[0].first.empty() || subtree[0].second.size() != 1)
-                {
-                    BMCWEB_LOG_DEBUG << "Error getting bmc D-Bus object!";
-                    messages::internalError(asyncResp->res);
-                    return;
-                }
-
-                const std::string& path = subtree[0].first;
-                const std::string& connectionName = subtree[0].second[0].first;
-
-                for (const auto& interfaceName : subtree[0].second[0].second)
-                {
-                    if (interfaceName ==
-                        "xyz.openbmc_project.Inventory.Decorator.Asset")
-                    {
-                        crow::connections::systemBus->async_method_call(
-                            [asyncResp](
-                                const boost::system::error_code ec,
-                                const std::vector<std::pair<
-                                    std::string, std::variant<std::string>>>&
-                                    propertiesList) {
-                                if (ec)
-                                {
-                                    BMCWEB_LOG_DEBUG << "Can't get bmc asset!";
-                                    return;
-                                }
-                                for (const std::pair<std::string,
-                                                     std::variant<std::string>>&
-                                         property : propertiesList)
-                                {
-                                    const std::string& propertyName =
-                                        property.first;
-
-                                    if ((propertyName == "PartNumber") ||
-                                        (propertyName == "SerialNumber") ||
-                                        (propertyName == "Manufacturer") ||
-                                        (propertyName == "Model") ||
-                                        (propertyName == "SparePartNumber"))
-                                    {
-                                        const std::string* value =
-                                            std::get_if<std::string>(
-                                                &property.second);
-                                        if (value == nullptr)
-                                        {
-                                            // illegal property
-                                            messages::internalError(
-                                                asyncResp->res);
-                                            return;
-                                        }
-                                        asyncResp->res.jsonValue[propertyName] =
-                                            *value;
-                                    }
-                                }
-                            },
-                            connectionName, path,
-                            "org.freedesktop.DBus.Properties", "GetAll",
-                            "xyz.openbmc_project.Inventory.Decorator.Asset");
-                    }
-                    else if (interfaceName == "xyz.openbmc_project.Inventory."
-                                              "Decorator.LocationCode")
-                    {
-                        getLocation(asyncResp, connectionName, path);
-                    }
-                }
-            },
-            "xyz.openbmc_project.ObjectMapper",
-            "/xyz/openbmc_project/object_mapper",
-            "xyz.openbmc_project.ObjectMapper", "GetSubTree",
-            "/xyz/openbmc_project/inventory", int32_t(0),
-            std::array<const char*, 1>{
-                "xyz.openbmc_project.Inventory.Item.Bmc"});
-    }
-
-    void doPatch(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                 const crow::Request& req,
-                 const std::vector<std::string>&) override
-    {
-        std::optional<nlohmann::json> oem;
-        std::optional<nlohmann::json> links;
-        std::optional<std::string> datetime;
-
-        if (!json_util::readJson(req, asyncResp->res, "Oem", oem, "DateTime",
-                                 datetime, "Links", links))
-        {
-            return;
-        }
-
-        if (oem)
-        {
-            std::optional<nlohmann::json> openbmc;
-            if (!redfish::json_util::readJson(*oem, asyncResp->res, "OpenBmc",
-                                              openbmc))
+    crow::connections::systemBus->async_method_call(
+        [aResp](const boost::system::error_code ec,
+                std::variant<uint64_t>& lastResetTime) {
+            if (ec)
             {
-                BMCWEB_LOG_ERROR
-                    << "Illegal Property "
-                    << oem->dump(2, ' ', true,
-                                 nlohmann::json::error_handler_t::replace);
+                BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
                 return;
             }
-            if (openbmc)
+
+            const uint64_t* lastResetTimePtr =
+                std::get_if<uint64_t>(&lastResetTime);
+
+            if (!lastResetTimePtr)
             {
-                std::optional<nlohmann::json> fan;
-                if (!redfish::json_util::readJson(*openbmc, asyncResp->res,
-                                                  "Fan", fan))
-                {
-                    BMCWEB_LOG_ERROR
-                        << "Illegal Property "
-                        << openbmc->dump(
-                               2, ' ', true,
-                               nlohmann::json::error_handler_t::replace);
-                    return;
-                }
-                if (fan)
-                {
-                    auto pid = std::make_shared<SetPIDValues>(asyncResp, *fan);
-                    pid->run();
-                }
-            }
-        }
-        if (links)
-        {
-            std::optional<nlohmann::json> activeSoftwareImage;
-            if (!redfish::json_util::readJson(*links, asyncResp->res,
-                                              "ActiveSoftwareImage",
-                                              activeSoftwareImage))
-            {
+                messages::internalError(aResp->res);
                 return;
             }
-            if (activeSoftwareImage)
+            // LastRebootTime is epoch time, in milliseconds
+            // https://github.com/openbmc/phosphor-dbus-interfaces/blob/7f9a128eb9296e926422ddc312c148b625890bb6/xyz/openbmc_project/State/BMC.interface.yaml#L19
+            time_t lastResetTimeStamp =
+                static_cast<time_t>(*lastResetTimePtr / 1000);
+
+            // Convert to ISO 8601 standard
+            aResp->res.jsonValue["LastResetTime"] =
+                crow::utility::getDateTime(lastResetTimeStamp);
+        },
+        "xyz.openbmc_project.State.BMC", "/xyz/openbmc_project/state/bmc0",
+        "org.freedesktop.DBus.Properties", "Get",
+        "xyz.openbmc_project.State.BMC", "LastRebootTime");
+}
+
+/**
+ * @brief Set the running firmware image
+ *
+ * @param[i,o] aResp - Async response object
+ * @param[i] runningFirmwareTarget - Image to make the running image
+ *
+ * @return void
+ */
+inline void
+    setActiveFirmwareImage(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
+                           const std::string& runningFirmwareTarget)
+{
+    // Get the Id from /redfish/v1/UpdateService/FirmwareInventory/<Id>
+    std::string::size_type idPos = runningFirmwareTarget.rfind('/');
+    if (idPos == std::string::npos)
+    {
+        messages::propertyValueNotInList(aResp->res, runningFirmwareTarget,
+                                         "@odata.id");
+        BMCWEB_LOG_DEBUG << "Can't parse firmware ID!";
+        return;
+    }
+    idPos++;
+    if (idPos >= runningFirmwareTarget.size())
+    {
+        messages::propertyValueNotInList(aResp->res, runningFirmwareTarget,
+                                         "@odata.id");
+        BMCWEB_LOG_DEBUG << "Invalid firmware ID.";
+        return;
+    }
+    std::string firmwareId = runningFirmwareTarget.substr(idPos);
+
+    // Make sure the image is valid before setting priority
+    crow::connections::systemBus->async_method_call(
+        [aResp, firmwareId, runningFirmwareTarget](
+            const boost::system::error_code ec, ManagedObjectType& subtree) {
+            if (ec)
             {
-                std::optional<std::string> odataId;
-                if (!json_util::readJson(*activeSoftwareImage, asyncResp->res,
-                                         "@odata.id", odataId))
+                BMCWEB_LOG_DEBUG << "D-Bus response error getting objects.";
+                messages::internalError(aResp->res);
+                return;
+            }
+
+            if (subtree.size() == 0)
+            {
+                BMCWEB_LOG_DEBUG << "Can't find image!";
+                messages::internalError(aResp->res);
+                return;
+            }
+
+            bool foundImage = false;
+            for (auto& object : subtree)
+            {
+                const std::string& path =
+                    static_cast<const std::string&>(object.first);
+                std::size_t idPos2 = path.rfind('/');
+
+                if (idPos2 == std::string::npos)
                 {
-                    return;
+                    continue;
                 }
 
-                if (odataId)
+                idPos2++;
+                if (idPos2 >= path.size())
                 {
-                    setActiveFirmwareImage(asyncResp, *odataId);
+                    continue;
+                }
+
+                if (path.substr(idPos2) == firmwareId)
+                {
+                    foundImage = true;
+                    break;
                 }
             }
-        }
-        if (datetime)
-        {
-            setDateTime(asyncResp, std::move(*datetime));
-        }
-    }
 
-    void getLastResetTime(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
-    {
-        BMCWEB_LOG_DEBUG << "Getting Manager Last Reset Time";
+            if (!foundImage)
+            {
+                messages::propertyValueNotInList(
+                    aResp->res, runningFirmwareTarget, "@odata.id");
+                BMCWEB_LOG_DEBUG << "Invalid firmware ID.";
+                return;
+            }
 
-        crow::connections::systemBus->async_method_call(
-            [aResp](const boost::system::error_code ec,
-                    std::variant<uint64_t>& lastResetTime) {
-                if (ec)
-                {
-                    BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
-                    return;
-                }
+            BMCWEB_LOG_DEBUG
+                << "Setting firmware version " + firmwareId + " to priority 0.";
 
-                const uint64_t* lastResetTimePtr =
-                    std::get_if<uint64_t>(&lastResetTime);
-
-                if (!lastResetTimePtr)
-                {
-                    messages::internalError(aResp->res);
-                    return;
-                }
-                // LastRebootTime is epoch time, in milliseconds
-                // https://github.com/openbmc/phosphor-dbus-interfaces/blob/7f9a128eb9296e926422ddc312c148b625890bb6/xyz/openbmc_project/State/BMC.interface.yaml#L19
-                time_t lastResetTimeStamp =
-                    static_cast<time_t>(*lastResetTimePtr / 1000);
-
-                // Convert to ISO 8601 standard
-                aResp->res.jsonValue["LastResetTime"] =
-                    crow::utility::getDateTime(lastResetTimeStamp);
-            },
-            "xyz.openbmc_project.State.BMC", "/xyz/openbmc_project/state/bmc0",
-            "org.freedesktop.DBus.Properties", "Get",
-            "xyz.openbmc_project.State.BMC", "LastRebootTime");
-    }
-
-    /**
-     * @brief Set the running firmware image
-     *
-     * @param[i,o] aResp - Async response object
-     * @param[i] runningFirmwareTarget - Image to make the running image
-     *
-     * @return void
-     */
-    void setActiveFirmwareImage(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
-                                const std::string& runningFirmwareTarget)
-    {
-        // Get the Id from /redfish/v1/UpdateService/FirmwareInventory/<Id>
-        std::string::size_type idPos = runningFirmwareTarget.rfind('/');
-        if (idPos == std::string::npos)
-        {
-            messages::propertyValueNotInList(aResp->res, runningFirmwareTarget,
-                                             "@odata.id");
-            BMCWEB_LOG_DEBUG << "Can't parse firmware ID!";
-            return;
-        }
-        idPos++;
-        if (idPos >= runningFirmwareTarget.size())
-        {
-            messages::propertyValueNotInList(aResp->res, runningFirmwareTarget,
-                                             "@odata.id");
-            BMCWEB_LOG_DEBUG << "Invalid firmware ID.";
-            return;
-        }
-        std::string firmwareId = runningFirmwareTarget.substr(idPos);
-
-        // Make sure the image is valid before setting priority
-        crow::connections::systemBus->async_method_call(
-            [aResp, firmwareId,
-             runningFirmwareTarget](const boost::system::error_code ec,
-                                    ManagedObjectType& subtree) {
-                if (ec)
-                {
-                    BMCWEB_LOG_DEBUG << "D-Bus response error getting objects.";
-                    messages::internalError(aResp->res);
-                    return;
-                }
-
-                if (subtree.size() == 0)
-                {
-                    BMCWEB_LOG_DEBUG << "Can't find image!";
-                    messages::internalError(aResp->res);
-                    return;
-                }
-
-                bool foundImage = false;
-                for (auto& object : subtree)
-                {
-                    const std::string& path =
-                        static_cast<const std::string&>(object.first);
-                    std::size_t idPos2 = path.rfind('/');
-
-                    if (idPos2 == std::string::npos)
-                    {
-                        continue;
-                    }
-
-                    idPos2++;
-                    if (idPos2 >= path.size())
-                    {
-                        continue;
-                    }
-
-                    if (path.substr(idPos2) == firmwareId)
-                    {
-                        foundImage = true;
-                        break;
-                    }
-                }
-
-                if (!foundImage)
-                {
-                    messages::propertyValueNotInList(
-                        aResp->res, runningFirmwareTarget, "@odata.id");
-                    BMCWEB_LOG_DEBUG << "Invalid firmware ID.";
-                    return;
-                }
-
-                BMCWEB_LOG_DEBUG << "Setting firmware version " + firmwareId +
-                                        " to priority 0.";
-
-                // Only support Immediate
-                // An addition could be a Redfish Setting like
-                // ActiveSoftwareImageApplyTime and support OnReset
-                crow::connections::systemBus->async_method_call(
-                    [aResp](const boost::system::error_code ec) {
-                        if (ec)
-                        {
-                            BMCWEB_LOG_DEBUG << "D-Bus response error setting.";
-                            messages::internalError(aResp->res);
-                            return;
-                        }
-                        doBMCGracefulRestart(aResp);
-                    },
-
-                    "xyz.openbmc_project.Software.BMC.Updater",
-                    "/xyz/openbmc_project/software/" + firmwareId,
-                    "org.freedesktop.DBus.Properties", "Set",
-                    "xyz.openbmc_project.Software.RedundancyPriority",
-                    "Priority", std::variant<uint8_t>(static_cast<uint8_t>(0)));
-            },
-            "xyz.openbmc_project.Software.BMC.Updater",
-            "/xyz/openbmc_project/software",
-            "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
-    }
-
-    void setDateTime(std::shared_ptr<bmcweb::AsyncResp> aResp,
-                     std::string datetime) const
-    {
-        BMCWEB_LOG_DEBUG << "Set date time: " << datetime;
-
-        std::stringstream stream(datetime);
-        // Convert from ISO 8601 to boost local_time
-        // (BMC only has time in UTC)
-        boost::posix_time::ptime posixTime;
-        boost::posix_time::ptime epoch(boost::gregorian::date(1970, 1, 1));
-        // Facet gets deleted with the stringsteam
-        auto ifc = std::make_unique<boost::local_time::local_time_input_facet>(
-            "%Y-%m-%d %H:%M:%S%F %ZP");
-        stream.imbue(std::locale(stream.getloc(), ifc.release()));
-
-        boost::local_time::local_date_time ldt(
-            boost::local_time::not_a_date_time);
-
-        if (stream >> ldt)
-        {
-            posixTime = ldt.utc_time();
-            boost::posix_time::time_duration dur = posixTime - epoch;
-            uint64_t durMicroSecs =
-                static_cast<uint64_t>(dur.total_microseconds());
+            // Only support Immediate
+            // An addition could be a Redfish Setting like
+            // ActiveSoftwareImageApplyTime and support OnReset
             crow::connections::systemBus->async_method_call(
-                [aResp{std::move(aResp)}, datetime{std::move(datetime)}](
-                    const boost::system::error_code ec) {
+                [aResp](const boost::system::error_code ec) {
                     if (ec)
                     {
-                        BMCWEB_LOG_DEBUG << "Failed to set elapsed time. "
-                                            "DBUS response error "
-                                         << ec;
+                        BMCWEB_LOG_DEBUG << "D-Bus response error setting.";
                         messages::internalError(aResp->res);
                         return;
                     }
-                    aResp->res.jsonValue["DateTime"] = datetime;
+                    doBMCGracefulRestart(aResp);
                 },
-                "xyz.openbmc_project.Time.Manager",
-                "/xyz/openbmc_project/time/bmc",
+
+                "xyz.openbmc_project.Software.BMC.Updater",
+                "/xyz/openbmc_project/software/" + firmwareId,
                 "org.freedesktop.DBus.Properties", "Set",
-                "xyz.openbmc_project.Time.EpochTime", "Elapsed",
-                std::variant<uint64_t>(durMicroSecs));
-        }
-        else
-        {
-            messages::propertyValueFormatError(aResp->res, datetime,
-                                               "DateTime");
-            return;
-        }
-    }
+                "xyz.openbmc_project.Software.RedundancyPriority", "Priority",
+                std::variant<uint8_t>(static_cast<uint8_t>(0)));
+        },
+        "xyz.openbmc_project.Software.BMC.Updater",
+        "/xyz/openbmc_project/software", "org.freedesktop.DBus.ObjectManager",
+        "GetManagedObjects");
+}
 
-    std::string uuid;
-};
-
-class ManagerCollection : public Node
+inline void setDateTime(std::shared_ptr<bmcweb::AsyncResp> aResp,
+                        std::string datetime)
 {
-  public:
-    ManagerCollection(App& app) : Node(app, "/redfish/v1/Managers/")
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-    }
+    BMCWEB_LOG_DEBUG << "Set date time: " << datetime;
 
-  private:
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&, const std::vector<std::string>&) override
+    std::stringstream stream(datetime);
+    // Convert from ISO 8601 to boost local_time
+    // (BMC only has time in UTC)
+    boost::posix_time::ptime posixTime;
+    boost::posix_time::ptime epoch(boost::gregorian::date(1970, 1, 1));
+    // Facet gets deleted with the stringsteam
+    auto ifc = std::make_unique<boost::local_time::local_time_input_facet>(
+        "%Y-%m-%d %H:%M:%S%F %ZP");
+    stream.imbue(std::locale(stream.getloc(), ifc.release()));
+
+    boost::local_time::local_date_time ldt(boost::local_time::not_a_date_time);
+
+    if (stream >> ldt)
     {
-        // Collections don't include the static data added by SubRoute
-        // because it has a duplicate entry for members
-        asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Managers";
-        asyncResp->res.jsonValue["@odata.type"] =
-            "#ManagerCollection.ManagerCollection";
-        asyncResp->res.jsonValue["Name"] = "Manager Collection";
-        asyncResp->res.jsonValue["Members@odata.count"] = 1;
-        asyncResp->res.jsonValue["Members"] = {
-            {{"@odata.id", "/redfish/v1/Managers/bmc"}}};
+        posixTime = ldt.utc_time();
+        boost::posix_time::time_duration dur = posixTime - epoch;
+        uint64_t durMicroSecs = static_cast<uint64_t>(dur.total_microseconds());
+        crow::connections::systemBus->async_method_call(
+            [aResp{std::move(aResp)}, datetime{std::move(datetime)}](
+                const boost::system::error_code ec) {
+                if (ec)
+                {
+                    BMCWEB_LOG_DEBUG << "Failed to set elapsed time. "
+                                        "DBUS response error "
+                                     << ec;
+                    messages::internalError(aResp->res);
+                    return;
+                }
+                aResp->res.jsonValue["DateTime"] = datetime;
+            },
+            "xyz.openbmc_project.Time.Manager", "/xyz/openbmc_project/time/bmc",
+            "org.freedesktop.DBus.Properties", "Set",
+            "xyz.openbmc_project.Time.EpochTime", "Elapsed",
+            std::variant<uint64_t>(durMicroSecs));
     }
-};
+    else
+    {
+        messages::propertyValueFormatError(aResp->res, datetime, "DateTime");
+        return;
+    }
+}
+
+inline void requestRoutesManager(App& app)
+{
+    std::string uuid = persistent_data::getConfig().systemUuid;
+
+    BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/")
+        .privileges({"Login"})
+        .methods(boost::beast::http::verb::get)([uuid](const crow::Request&,
+                                                       const std::shared_ptr<
+                                                           bmcweb::AsyncResp>&
+                                                           asyncResp) {
+            asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Managers/bmc";
+            asyncResp->res.jsonValue["@odata.type"] =
+                "#Manager.v1_11_0.Manager";
+            asyncResp->res.jsonValue["Id"] = "bmc";
+            asyncResp->res.jsonValue["Name"] = "OpenBmc Manager";
+            asyncResp->res.jsonValue["Description"] =
+                "Baseboard Management Controller";
+            asyncResp->res.jsonValue["PowerState"] = "On";
+            asyncResp->res.jsonValue["Status"] = {{"State", "Enabled"},
+                                                  {"Health", "OK"}};
+            asyncResp->res.jsonValue["ManagerType"] = "BMC";
+            asyncResp->res.jsonValue["UUID"] = systemd_utils::getUuid();
+            asyncResp->res.jsonValue["ServiceEntryPointUUID"] = uuid;
+            asyncResp->res.jsonValue["Model"] =
+                "OpenBmc"; // TODO(ed), get model
+
+            asyncResp->res.jsonValue["LogServices"] = {
+                {"@odata.id", "/redfish/v1/Managers/bmc/LogServices"}};
+
+            asyncResp->res.jsonValue["NetworkProtocol"] = {
+                {"@odata.id", "/redfish/v1/Managers/bmc/NetworkProtocol"}};
+
+            asyncResp->res.jsonValue["EthernetInterfaces"] = {
+                {"@odata.id", "/redfish/v1/Managers/bmc/EthernetInterfaces"}};
+
+#ifdef BMCWEB_ENABLE_VM_NBDPROXY
+            asyncResp->res.jsonValue["VirtualMedia"] = {
+                {"@odata.id", "/redfish/v1/Managers/bmc/VirtualMedia"}};
+#endif // BMCWEB_ENABLE_VM_NBDPROXY
+
+            // default oem data
+            nlohmann::json& oem = asyncResp->res.jsonValue["Oem"];
+            nlohmann::json& oemOpenbmc = oem["OpenBmc"];
+            oem["@odata.type"] = "#OemManager.Oem";
+            oem["@odata.id"] = "/redfish/v1/Managers/bmc#/Oem";
+            oemOpenbmc["@odata.type"] = "#OemManager.OpenBmc";
+            oemOpenbmc["@odata.id"] = "/redfish/v1/Managers/bmc#/Oem/OpenBmc";
+            oemOpenbmc["Certificates"] = {
+                {"@odata.id",
+                 "/redfish/v1/Managers/bmc/Truststore/Certificates"}};
+
+            // Manager.Reset (an action) can be many values, OpenBMC only
+            // supports BMC reboot.
+            nlohmann::json& managerReset =
+                asyncResp->res.jsonValue["Actions"]["#Manager.Reset"];
+            managerReset["target"] =
+                "/redfish/v1/Managers/bmc/Actions/Manager.Reset";
+            managerReset["@Redfish.ActionInfo"] =
+                "/redfish/v1/Managers/bmc/ResetActionInfo";
+
+            // ResetToDefaults (Factory Reset) has values like
+            // PreserveNetworkAndUsers and PreserveNetwork that aren't supported
+            // on OpenBMC
+            nlohmann::json& resetToDefaults =
+                asyncResp->res.jsonValue["Actions"]["#Manager.ResetToDefaults"];
+            resetToDefaults["target"] =
+                "/redfish/v1/Managers/bmc/Actions/Manager.ResetToDefaults";
+            resetToDefaults["ResetType@Redfish.AllowableValues"] = {"ResetAll"};
+
+            asyncResp->res.jsonValue["DateTime"] = crow::utility::dateTimeNow();
+
+            // Fill in SerialConsole info
+            asyncResp->res.jsonValue["SerialConsole"]["ServiceEnabled"] = true;
+            asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] =
+                15;
+            asyncResp->res.jsonValue["SerialConsole"]["ConnectTypesSupported"] =
+                {"IPMI", "SSH"};
+#ifdef BMCWEB_ENABLE_KVM
+            // Fill in GraphicalConsole info
+            asyncResp->res.jsonValue["GraphicalConsole"]["ServiceEnabled"] =
+                true;
+            asyncResp->res
+                .jsonValue["GraphicalConsole"]["MaxConcurrentSessions"] = 4;
+            asyncResp->res.jsonValue["GraphicalConsole"]
+                                    ["ConnectTypesSupported"] = {"KVMIP"};
+#endif // BMCWEB_ENABLE_KVM
+
+            asyncResp->res.jsonValue["Links"]["ManagerForServers@odata.count"] =
+                1;
+            asyncResp->res.jsonValue["Links"]["ManagerForServers"] = {
+                {{"@odata.id", "/redfish/v1/Systems/system"}}};
+
+            auto health = std::make_shared<HealthPopulate>(asyncResp);
+            health->isManagersHealth = true;
+            health->populate();
+
+            fw_util::populateFirmwareInformation(asyncResp, fw_util::bmcPurpose,
+                                                 "FirmwareVersion", true);
+
+            managerGetLastResetTime(asyncResp);
+
+            auto pids = std::make_shared<GetPIDValues>(asyncResp);
+            pids->run();
+
+            getMainChassisId(
+                asyncResp, [](const std::string& chassisId,
+                              const std::shared_ptr<bmcweb::AsyncResp>& aRsp) {
+                    aRsp->res
+                        .jsonValue["Links"]["ManagerForChassis@odata.count"] =
+                        1;
+                    aRsp->res.jsonValue["Links"]["ManagerForChassis"] = {
+                        {{"@odata.id", "/redfish/v1/Chassis/" + chassisId}}};
+                    aRsp->res.jsonValue["Links"]["ManagerInChassis"] = {
+                        {"@odata.id", "/redfish/v1/Chassis/" + chassisId}};
+                });
+
+            static bool started = false;
+
+            if (!started)
+            {
+                crow::connections::systemBus->async_method_call(
+                    [asyncResp](const boost::system::error_code ec,
+                                const std::variant<double>& resp) {
+                        if (ec)
+                        {
+                            BMCWEB_LOG_ERROR << "Error while getting progress";
+                            messages::internalError(asyncResp->res);
+                            return;
+                        }
+                        const double* val = std::get_if<double>(&resp);
+                        if (val == nullptr)
+                        {
+                            BMCWEB_LOG_ERROR
+                                << "Invalid response while getting progress";
+                            messages::internalError(asyncResp->res);
+                            return;
+                        }
+                        if (*val < 1.0)
+                        {
+                            asyncResp->res.jsonValue["Status"]["State"] =
+                                "Starting";
+                            started = true;
+                        }
+                    },
+                    "org.freedesktop.systemd1", "/org/freedesktop/systemd1",
+                    "org.freedesktop.DBus.Properties", "Get",
+                    "org.freedesktop.systemd1.Manager", "Progress");
+            }
+
+            crow::connections::systemBus->async_method_call(
+                [asyncResp](
+                    const boost::system::error_code ec,
+                    const std::vector<
+                        std::pair<std::string,
+                                  std::vector<std::pair<
+                                      std::string, std::vector<std::string>>>>>&
+                        subtree) {
+                    if (ec)
+                    {
+                        BMCWEB_LOG_DEBUG
+                            << "D-Bus response error on GetSubTree " << ec;
+                        return;
+                    }
+                    if (subtree.size() == 0)
+                    {
+                        BMCWEB_LOG_DEBUG << "Can't find bmc D-Bus object!";
+                        return;
+                    }
+                    // Assume only 1 bmc D-Bus object
+                    // Throw an error if there is more than 1
+                    if (subtree.size() > 1)
+                    {
+                        BMCWEB_LOG_DEBUG
+                            << "Found more than 1 bmc D-Bus object!";
+                        messages::internalError(asyncResp->res);
+                        return;
+                    }
+
+                    if (subtree[0].first.empty() ||
+                        subtree[0].second.size() != 1)
+                    {
+                        BMCWEB_LOG_DEBUG << "Error getting bmc D-Bus object!";
+                        messages::internalError(asyncResp->res);
+                        return;
+                    }
+
+                    const std::string& path = subtree[0].first;
+                    const std::string& connectionName =
+                        subtree[0].second[0].first;
+
+                    for (const auto& interfaceName :
+                         subtree[0].second[0].second)
+                    {
+                        if (interfaceName ==
+                            "xyz.openbmc_project.Inventory.Decorator.Asset")
+                        {
+                            crow::connections::systemBus->async_method_call(
+                                [asyncResp](
+                                    const boost::system::error_code ec,
+                                    const std::vector<
+                                        std::pair<std::string,
+                                                  std::variant<std::string>>>&
+                                        propertiesList) {
+                                    if (ec)
+                                    {
+                                        BMCWEB_LOG_DEBUG
+                                            << "Can't get bmc asset!";
+                                        return;
+                                    }
+                                    for (const std::pair<
+                                             std::string,
+                                             std::variant<std::string>>&
+                                             property : propertiesList)
+                                    {
+                                        const std::string& propertyName =
+                                            property.first;
+
+                                        if ((propertyName == "PartNumber") ||
+                                            (propertyName == "SerialNumber") ||
+                                            (propertyName == "Manufacturer") ||
+                                            (propertyName == "Model") ||
+                                            (propertyName == "SparePartNumber"))
+                                        {
+                                            const std::string* value =
+                                                std::get_if<std::string>(
+                                                    &property.second);
+                                            if (value == nullptr)
+                                            {
+                                                // illegal property
+                                                messages::internalError(
+                                                    asyncResp->res);
+                                                return;
+                                            }
+                                            asyncResp->res
+                                                .jsonValue[propertyName] =
+                                                *value;
+                                        }
+                                    }
+                                },
+                                connectionName, path,
+                                "org.freedesktop.DBus.Properties", "GetAll",
+                                "xyz.openbmc_project.Inventory.Decorator."
+                                "Asset");
+                        }
+                        else if (interfaceName ==
+                                 "xyz.openbmc_project.Inventory."
+                                 "Decorator.LocationCode")
+                        {
+                            getLocation(asyncResp, connectionName, path);
+                        }
+                    }
+                },
+                "xyz.openbmc_project.ObjectMapper",
+                "/xyz/openbmc_project/object_mapper",
+                "xyz.openbmc_project.ObjectMapper", "GetSubTree",
+                "/xyz/openbmc_project/inventory", int32_t(0),
+                std::array<const char*, 1>{
+                    "xyz.openbmc_project.Inventory.Item.Bmc"});
+        });
+
+    BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/")
+        .privileges({"ConfigureManager"})
+        .methods(
+            boost::beast::http::verb::
+                patch)([](const crow::Request& req,
+                          const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+            std::optional<nlohmann::json> oem;
+            std::optional<nlohmann::json> links;
+            std::optional<std::string> datetime;
+
+            if (!json_util::readJson(req, asyncResp->res, "Oem", oem,
+                                     "DateTime", datetime, "Links", links))
+            {
+                return;
+            }
+
+            if (oem)
+            {
+                std::optional<nlohmann::json> openbmc;
+                if (!redfish::json_util::readJson(*oem, asyncResp->res,
+                                                  "OpenBmc", openbmc))
+                {
+                    BMCWEB_LOG_ERROR
+                        << "Illegal Property "
+                        << oem->dump(2, ' ', true,
+                                     nlohmann::json::error_handler_t::replace);
+                    return;
+                }
+                if (openbmc)
+                {
+                    std::optional<nlohmann::json> fan;
+                    if (!redfish::json_util::readJson(*openbmc, asyncResp->res,
+                                                      "Fan", fan))
+                    {
+                        BMCWEB_LOG_ERROR
+                            << "Illegal Property "
+                            << openbmc->dump(
+                                   2, ' ', true,
+                                   nlohmann::json::error_handler_t::replace);
+                        return;
+                    }
+                    if (fan)
+                    {
+                        auto pid =
+                            std::make_shared<SetPIDValues>(asyncResp, *fan);
+                        pid->run();
+                    }
+                }
+            }
+            if (links)
+            {
+                std::optional<nlohmann::json> activeSoftwareImage;
+                if (!redfish::json_util::readJson(*links, asyncResp->res,
+                                                  "ActiveSoftwareImage",
+                                                  activeSoftwareImage))
+                {
+                    return;
+                }
+                if (activeSoftwareImage)
+                {
+                    std::optional<std::string> odataId;
+                    if (!json_util::readJson(*activeSoftwareImage,
+                                             asyncResp->res, "@odata.id",
+                                             odataId))
+                    {
+                        return;
+                    }
+
+                    if (odataId)
+                    {
+                        setActiveFirmwareImage(asyncResp, *odataId);
+                    }
+                }
+            }
+            if (datetime)
+            {
+                setDateTime(asyncResp, std::move(*datetime));
+            }
+        });
+}
+
+inline void requestRoutesManagerCollection(App& app)
+{
+    BMCWEB_ROUTE(app, "/redfish/v1/Managers/")
+        .privileges({"Login"})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                // Collections don't include the static data added by SubRoute
+                // because it has a duplicate entry for members
+                asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Managers";
+                asyncResp->res.jsonValue["@odata.type"] =
+                    "#ManagerCollection.ManagerCollection";
+                asyncResp->res.jsonValue["Name"] = "Manager Collection";
+                asyncResp->res.jsonValue["Members@odata.count"] = 1;
+                asyncResp->res.jsonValue["Members"] = {
+                    {{"@odata.id", "/redfish/v1/Managers/bmc"}}};
+            });
+}
 } // namespace redfish
diff --git a/redfish-core/lib/memory.hpp b/redfish-core/lib/memory.hpp
index 70886d2..465beae 100644
--- a/redfish-core/lib/memory.hpp
+++ b/redfish-core/lib/memory.hpp
@@ -17,9 +17,9 @@
 
 #include "health.hpp"
 
+#include <app.hpp>
 #include <boost/container/flat_map.hpp>
 #include <boost/format.hpp>
-#include <node.hpp>
 #include <utils/collection.hpp>
 #include <utils/json_utils.hpp>
 
@@ -880,83 +880,46 @@
             "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition"});
 }
 
-class MemoryCollection : public Node
+inline void requestRoutesMemoryCollection(App& app)
 {
-  public:
-    /*
-     * Default Constructor
-     */
-    MemoryCollection(App& app) : Node(app, "/redfish/v1/Systems/system/Memory/")
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
-    }
-
-  private:
     /**
      * Functions triggers appropriate requests on DBus
      */
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&, const std::vector<std::string>&) override
-    {
-        asyncResp->res.jsonValue["@odata.type"] =
-            "#MemoryCollection.MemoryCollection";
-        asyncResp->res.jsonValue["Name"] = "Memory Module Collection";
-        asyncResp->res.jsonValue["@odata.id"] =
-            "/redfish/v1/Systems/system/Memory";
+    BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/Memory/")
+        .privileges({"Login"})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                asyncResp->res.jsonValue["@odata.type"] =
+                    "#MemoryCollection.MemoryCollection";
+                asyncResp->res.jsonValue["Name"] = "Memory Module Collection";
+                asyncResp->res.jsonValue["@odata.id"] =
+                    "/redfish/v1/Systems/system/Memory";
 
-        collection_util::getCollectionMembers(
-            asyncResp, "/redfish/v1/Systems/system/Memory",
-            {"xyz.openbmc_project.Inventory.Item.Dimm"});
-    }
-};
+                collection_util::getCollectionMembers(
+                    asyncResp, "/redfish/v1/Systems/system/Memory",
+                    {"xyz.openbmc_project.Inventory.Item.Dimm"});
+            });
+}
 
-class Memory : public Node
+inline void requestRoutesMemory(App& app)
 {
-  public:
-    /*
-     * Default Constructor
-     */
-    Memory(App& app) :
-        Node(app, "/redfish/v1/Systems/system/Memory/<str>/", std::string())
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
-    }
-
-  private:
     /**
      * Functions triggers appropriate requests on DBus
      */
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&,
-               const std::vector<std::string>& params) override
-    {
-        // Check if there is required param, truly entering this shall be
-        // impossible
-        if (params.size() != 1)
-        {
-            messages::internalError(asyncResp->res);
-            return;
-        }
-        const std::string& dimmId = params[0];
+    BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/Memory/<str>/")
+        .privileges({"Login"})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+               const std::string& dimmId) {
+                asyncResp->res.jsonValue["@odata.type"] =
+                    "#Memory.v1_11_0.Memory";
+                asyncResp->res.jsonValue["@odata.id"] =
+                    "/redfish/v1/Systems/system/Memory/" + dimmId;
 
-        asyncResp->res.jsonValue["@odata.type"] = "#Memory.v1_11_0.Memory";
-        asyncResp->res.jsonValue["@odata.id"] =
-            "/redfish/v1/Systems/system/Memory/" + dimmId;
-
-        getDimmData(asyncResp, dimmId);
-    }
-};
+                getDimmData(asyncResp, dimmId);
+            });
+}
 
 } // namespace redfish
diff --git a/redfish-core/lib/message_registries.hpp b/redfish-core/lib/message_registries.hpp
index 455bf70..d0757b3 100644
--- a/redfish-core/lib/message_registries.hpp
+++ b/redfish-core/lib/message_registries.hpp
@@ -15,257 +15,215 @@
 */
 #pragma once
 
-#include "node.hpp"
 #include "registries.hpp"
 #include "registries/base_message_registry.hpp"
 #include "registries/openbmc_message_registry.hpp"
 #include "registries/resource_event_message_registry.hpp"
 #include "registries/task_event_message_registry.hpp"
 
+#include <app.hpp>
+
 namespace redfish
 {
 
-class MessageRegistryFileCollection : public Node
+inline void requestRoutesMessageRegistryFileCollection(App& app)
 {
-  public:
-    MessageRegistryFileCollection(App& app) :
-        Node(app, "/redfish/v1/Registries/")
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-    }
-
-  private:
     /**
      * Functions triggers appropriate requests on DBus
      */
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&, const std::vector<std::string>&) override
-    {
-        // Collections don't include the static data added by SubRoute because
-        // it has a duplicate entry for members
+    BMCWEB_ROUTE(app, "/redfish/v1/Registries/")
+        .privileges({"Login"})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                // Collections don't include the static data added by SubRoute
+                // because it has a duplicate entry for members
 
-        asyncResp->res.jsonValue = {
-            {"@odata.type",
-             "#MessageRegistryFileCollection.MessageRegistryFileCollection"},
-            {"@odata.id", "/redfish/v1/Registries"},
-            {"Name", "MessageRegistryFile Collection"},
-            {"Description", "Collection of MessageRegistryFiles"},
-            {"Members@odata.count", 4},
-            {"Members",
-             {{{"@odata.id", "/redfish/v1/Registries/Base"}},
-              {{"@odata.id", "/redfish/v1/Registries/TaskEvent"}},
-              {{"@odata.id", "/redfish/v1/Registries/ResourceEvent"}},
-              {{"@odata.id", "/redfish/v1/Registries/OpenBMC"}}}}};
-    }
-};
+                asyncResp->res.jsonValue = {
+                    {"@odata.type", "#MessageRegistryFileCollection."
+                                    "MessageRegistryFileCollection"},
+                    {"@odata.id", "/redfish/v1/Registries"},
+                    {"Name", "MessageRegistryFile Collection"},
+                    {"Description", "Collection of MessageRegistryFiles"},
+                    {"Members@odata.count", 4},
+                    {"Members",
+                     {{{"@odata.id", "/redfish/v1/Registries/Base"}},
+                      {{"@odata.id", "/redfish/v1/Registries/TaskEvent"}},
+                      {{"@odata.id", "/redfish/v1/Registries/ResourceEvent"}},
+                      {{"@odata.id", "/redfish/v1/Registries/OpenBMC"}}}}};
+            });
+}
 
-class MessageRegistryFile : public Node
+inline void requestRoutesMessageRegistryFile(App& app)
 {
-  public:
-    MessageRegistryFile(App& app) :
-        Node(app, "/redfish/v1/Registries/<str>/", std::string())
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-    }
+    BMCWEB_ROUTE(app, "/redfish/v1/Registries/<str>/")
+        .privileges({"Login"})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+               const std::string& registry) {
+                const message_registries::Header* header;
+                std::string dmtf = "DMTF ";
+                const char* url = nullptr;
 
-  private:
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&,
-               const std::vector<std::string>& params) override
-    {
-        if (params.size() != 1)
-        {
-            messages::internalError(asyncResp->res);
-            return;
-        }
-
-        const std::string& registry = params[0];
-        const message_registries::Header* header;
-        std::string dmtf = "DMTF ";
-        const char* url = nullptr;
-
-        if (registry == "Base")
-        {
-            header = &message_registries::base::header;
-            url = message_registries::base::url;
-        }
-        else if (registry == "TaskEvent")
-        {
-            header = &message_registries::task_event::header;
-            url = message_registries::task_event::url;
-        }
-        else if (registry == "OpenBMC")
-        {
-            header = &message_registries::openbmc::header;
-            dmtf.clear();
-        }
-        else if (registry == "ResourceEvent")
-        {
-            header = &message_registries::resource_event::header;
-            url = message_registries::resource_event::url;
-        }
-        else
-        {
-            messages::resourceNotFound(
-                asyncResp->res,
-                "#MessageRegistryFile.v1_1_0.MessageRegistryFile", registry);
-            return;
-        }
-
-        asyncResp->res.jsonValue = {
-            {"@odata.id", "/redfish/v1/Registries/" + registry},
-            {"@odata.type", "#MessageRegistryFile.v1_1_0.MessageRegistryFile"},
-            {"Name", registry + " Message Registry File"},
-            {"Description",
-             dmtf + registry + " Message Registry File Location"},
-            {"Id", header->registryPrefix},
-            {"Registry", header->id},
-            {"Languages", {"en"}},
-            {"Languages@odata.count", 1},
-            {"Location",
-             {{{"Language", "en"},
-               {"Uri",
-                "/redfish/v1/Registries/" + registry + "/" + registry}}}},
-            {"Location@odata.count", 1}};
-
-        if (url != nullptr)
-        {
-            asyncResp->res.jsonValue["Location"][0]["PublicationUri"] = url;
-        }
-    }
-};
-
-class MessageRegistry : public Node
-{
-  public:
-    MessageRegistry(App& app) :
-        Node(app, "/redfish/v1/Registries/<str>/<str>/", std::string(),
-             std::string())
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-    }
-
-  private:
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&,
-               const std::vector<std::string>& params) override
-    {
-        if (params.size() != 2)
-        {
-            messages::internalError(asyncResp->res);
-            return;
-        }
-
-        const std::string& registry = params[0];
-        const std::string& registry1 = params[1];
-
-        const message_registries::Header* header;
-        std::vector<const message_registries::MessageEntry*> registryEntries;
-        if (registry == "Base")
-        {
-            header = &message_registries::base::header;
-            for (const message_registries::MessageEntry& entry :
-                 message_registries::base::registry)
-            {
-                registryEntries.emplace_back(&entry);
-            }
-        }
-        else if (registry == "TaskEvent")
-        {
-            header = &message_registries::task_event::header;
-            for (const message_registries::MessageEntry& entry :
-                 message_registries::task_event::registry)
-            {
-                registryEntries.emplace_back(&entry);
-            }
-        }
-        else if (registry == "OpenBMC")
-        {
-            header = &message_registries::openbmc::header;
-            for (const message_registries::MessageEntry& entry :
-                 message_registries::openbmc::registry)
-            {
-                registryEntries.emplace_back(&entry);
-            }
-        }
-        else if (registry == "ResourceEvent")
-        {
-            header = &message_registries::resource_event::header;
-            for (const message_registries::MessageEntry& entry :
-                 message_registries::resource_event::registry)
-            {
-                registryEntries.emplace_back(&entry);
-            }
-        }
-        else
-        {
-            messages::resourceNotFound(
-                asyncResp->res,
-                "#MessageRegistryFile.v1_1_0.MessageRegistryFile", registry);
-            return;
-        }
-
-        if (registry != registry1)
-        {
-            messages::resourceNotFound(asyncResp->res, header->type, registry1);
-            return;
-        }
-
-        asyncResp->res.jsonValue = {
-            {"@Redfish.Copyright", header->copyright},
-            {"@odata.type", header->type},
-            {"Id", header->id},
-            {"Name", header->name},
-            {"Language", header->language},
-            {"Description", header->description},
-            {"RegistryPrefix", header->registryPrefix},
-            {"RegistryVersion", header->registryVersion},
-            {"OwningEntity", header->owningEntity}};
-
-        nlohmann::json& messageObj = asyncResp->res.jsonValue["Messages"];
-
-        // Go through the Message Registry and populate each Message
-        for (const message_registries::MessageEntry* message : registryEntries)
-        {
-            nlohmann::json& obj = messageObj[message->first];
-            obj = {{"Description", message->second.description},
-                   {"Message", message->second.message},
-                   {"Severity", message->second.severity},
-                   {"MessageSeverity", message->second.messageSeverity},
-                   {"NumberOfArgs", message->second.numberOfArgs},
-                   {"Resolution", message->second.resolution}};
-            if (message->second.numberOfArgs > 0)
-            {
-                nlohmann::json& messageParamArray = obj["ParamTypes"];
-                for (const char* str : message->second.paramTypes)
+                if (registry == "Base")
                 {
-                    if (str == nullptr)
-                    {
-                        break;
-                    }
-                    messageParamArray.push_back(str);
+                    header = &message_registries::base::header;
+                    url = message_registries::base::url;
                 }
-            }
-        }
-    }
-};
+                else if (registry == "TaskEvent")
+                {
+                    header = &message_registries::task_event::header;
+                    url = message_registries::task_event::url;
+                }
+                else if (registry == "OpenBMC")
+                {
+                    header = &message_registries::openbmc::header;
+                    dmtf.clear();
+                }
+                else if (registry == "ResourceEvent")
+                {
+                    header = &message_registries::resource_event::header;
+                    url = message_registries::resource_event::url;
+                }
+                else
+                {
+                    messages::resourceNotFound(
+                        asyncResp->res,
+                        "#MessageRegistryFile.v1_1_0.MessageRegistryFile",
+                        registry);
+                    return;
+                }
+
+                asyncResp->res.jsonValue = {
+                    {"@odata.id", "/redfish/v1/Registries/" + registry},
+                    {"@odata.type",
+                     "#MessageRegistryFile.v1_1_0.MessageRegistryFile"},
+                    {"Name", registry + " Message Registry File"},
+                    {"Description",
+                     dmtf + registry + " Message Registry File Location"},
+                    {"Id", header->registryPrefix},
+                    {"Registry", header->id},
+                    {"Languages", {"en"}},
+                    {"Languages@odata.count", 1},
+                    {"Location",
+                     {{{"Language", "en"},
+                       {"Uri", "/redfish/v1/Registries/" + registry + "/" +
+                                   registry}}}},
+                    {"Location@odata.count", 1}};
+
+                if (url != nullptr)
+                {
+                    asyncResp->res.jsonValue["Location"][0]["PublicationUri"] =
+                        url;
+                }
+            });
+}
+
+inline void requestRoutesMessageRegistry(App& app)
+{
+    BMCWEB_ROUTE(app, "/redfish/v1/Registries/<str>/<str>/")
+        .privileges({"Login"})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+               const std::string& registry, const std::string& registry1)
+
+            {
+                const message_registries::Header* header;
+                std::vector<const message_registries::MessageEntry*>
+                    registryEntries;
+                if (registry == "Base")
+                {
+                    header = &message_registries::base::header;
+                    for (const message_registries::MessageEntry& entry :
+                         message_registries::base::registry)
+                    {
+                        registryEntries.emplace_back(&entry);
+                    }
+                }
+                else if (registry == "TaskEvent")
+                {
+                    header = &message_registries::task_event::header;
+                    for (const message_registries::MessageEntry& entry :
+                         message_registries::task_event::registry)
+                    {
+                        registryEntries.emplace_back(&entry);
+                    }
+                }
+                else if (registry == "OpenBMC")
+                {
+                    header = &message_registries::openbmc::header;
+                    for (const message_registries::MessageEntry& entry :
+                         message_registries::openbmc::registry)
+                    {
+                        registryEntries.emplace_back(&entry);
+                    }
+                }
+                else if (registry == "ResourceEvent")
+                {
+                    header = &message_registries::resource_event::header;
+                    for (const message_registries::MessageEntry& entry :
+                         message_registries::resource_event::registry)
+                    {
+                        registryEntries.emplace_back(&entry);
+                    }
+                }
+                else
+                {
+                    messages::resourceNotFound(
+                        asyncResp->res,
+                        "#MessageRegistryFile.v1_1_0.MessageRegistryFile",
+                        registry);
+                    return;
+                }
+
+                if (registry != registry1)
+                {
+                    messages::resourceNotFound(asyncResp->res, header->type,
+                                               registry1);
+                    return;
+                }
+
+                asyncResp->res.jsonValue = {
+                    {"@Redfish.Copyright", header->copyright},
+                    {"@odata.type", header->type},
+                    {"Id", header->id},
+                    {"Name", header->name},
+                    {"Language", header->language},
+                    {"Description", header->description},
+                    {"RegistryPrefix", header->registryPrefix},
+                    {"RegistryVersion", header->registryVersion},
+                    {"OwningEntity", header->owningEntity}};
+
+                nlohmann::json& messageObj =
+                    asyncResp->res.jsonValue["Messages"];
+
+                // Go through the Message Registry and populate each Message
+                for (const message_registries::MessageEntry* message :
+                     registryEntries)
+                {
+                    nlohmann::json& obj = messageObj[message->first];
+                    obj = {{"Description", message->second.description},
+                           {"Message", message->second.message},
+                           {"Severity", message->second.severity},
+                           {"MessageSeverity", message->second.messageSeverity},
+                           {"NumberOfArgs", message->second.numberOfArgs},
+                           {"Resolution", message->second.resolution}};
+                    if (message->second.numberOfArgs > 0)
+                    {
+                        nlohmann::json& messageParamArray = obj["ParamTypes"];
+                        for (const char* str : message->second.paramTypes)
+                        {
+                            if (str == nullptr)
+                            {
+                                break;
+                            }
+                            messageParamArray.push_back(str);
+                        }
+                    }
+                }
+            });
+}
 
 } // namespace redfish
diff --git a/redfish-core/lib/metric_report.hpp b/redfish-core/lib/metric_report.hpp
index ad15a05..24e53f9 100644
--- a/redfish-core/lib/metric_report.hpp
+++ b/redfish-core/lib/metric_report.hpp
@@ -1,8 +1,9 @@
 #pragma once
 
-#include "node.hpp"
 #include "utils/telemetry_utils.hpp"
 
+#include <app.hpp>
+
 namespace redfish
 {
 
@@ -59,85 +60,43 @@
 }
 } // namespace telemetry
 
-class MetricReportCollection : public Node
+inline void requestRoutesMetricReportCollection(App& app)
 {
-  public:
-    MetricReportCollection(App& app) :
-        Node(app, "/redfish/v1/TelemetryService/MetricReports/")
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-    }
+    BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/MetricReports/")
+        .privileges({"Login"})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                asyncResp->res.jsonValue["@odata.type"] =
+                    "#MetricReportCollection.MetricReportCollection";
+                asyncResp->res.jsonValue["@odata.id"] =
+                    "/redfish/v1/TelemetryService/MetricReports";
+                asyncResp->res.jsonValue["Name"] = "Metric Report Collection";
 
-  private:
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&, const std::vector<std::string>&) override
-    {
-        asyncResp->res.jsonValue["@odata.type"] =
-            "#MetricReportCollection.MetricReportCollection";
-        asyncResp->res.jsonValue["@odata.id"] =
-            "/redfish/v1/TelemetryService/MetricReports";
-        asyncResp->res.jsonValue["Name"] = "Metric Report Collection";
+                telemetry::getReportCollection(asyncResp,
+                                               telemetry::metricReportUri);
+            });
+}
 
-        telemetry::getReportCollection(asyncResp, telemetry::metricReportUri);
-    }
-};
-
-class MetricReport : public Node
+inline void requestRoutesMetricReport(App& app)
 {
-  public:
-    MetricReport(App& app) :
-        Node(app, "/redfish/v1/TelemetryService/MetricReports/<str>/",
-             std::string())
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-    }
-
-  private:
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&,
-               const std::vector<std::string>& params) override
-    {
-
-        if (params.size() != 1)
-        {
-            messages::internalError(asyncResp->res);
-            return;
-        }
-
-        const std::string& id = params[0];
-        const std::string reportPath = telemetry::getDbusReportPath(id);
-        crow::connections::systemBus->async_method_call(
-            [asyncResp, id, reportPath](const boost::system::error_code& ec) {
-                if (ec.value() == EBADR ||
-                    ec == boost::system::errc::host_unreachable)
-                {
-                    messages::resourceNotFound(asyncResp->res, "MetricReport",
-                                               id);
-                    return;
-                }
-                if (ec)
-                {
-                    BMCWEB_LOG_ERROR << "respHandler DBus error " << ec;
-                    messages::internalError(asyncResp->res);
-                    return;
-                }
-
+    BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/MetricReports/<str>/")
+        .privileges({"Login"})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+               const std::string& id) {
+                const std::string reportPath = telemetry::getDbusReportPath(id);
                 crow::connections::systemBus->async_method_call(
-                    [asyncResp, id](
-                        const boost::system::error_code ec,
-                        const std::variant<telemetry::TimestampReadings>& ret) {
+                    [asyncResp, id,
+                     reportPath](const boost::system::error_code& ec) {
+                        if (ec.value() == EBADR ||
+                            ec == boost::system::errc::host_unreachable)
+                        {
+                            messages::resourceNotFound(asyncResp->res,
+                                                       "MetricReport", id);
+                            return;
+                        }
                         if (ec)
                         {
                             BMCWEB_LOG_ERROR << "respHandler DBus error " << ec;
@@ -145,14 +104,27 @@
                             return;
                         }
 
-                        telemetry::fillReport(asyncResp, id, ret);
+                        crow::connections::systemBus->async_method_call(
+                            [asyncResp,
+                             id](const boost::system::error_code ec,
+                                 const std::variant<
+                                     telemetry::TimestampReadings>& ret) {
+                                if (ec)
+                                {
+                                    BMCWEB_LOG_ERROR
+                                        << "respHandler DBus error " << ec;
+                                    messages::internalError(asyncResp->res);
+                                    return;
+                                }
+
+                                telemetry::fillReport(asyncResp, id, ret);
+                            },
+                            telemetry::service, reportPath,
+                            "org.freedesktop.DBus.Properties", "Get",
+                            telemetry::reportInterface, "Readings");
                     },
-                    telemetry::service, reportPath,
-                    "org.freedesktop.DBus.Properties", "Get",
-                    telemetry::reportInterface, "Readings");
-            },
-            telemetry::service, reportPath, telemetry::reportInterface,
-            "Update");
-    }
-};
+                    telemetry::service, reportPath, telemetry::reportInterface,
+                    "Update");
+            });
+}
 } // namespace redfish
diff --git a/redfish-core/lib/metric_report_definition.hpp b/redfish-core/lib/metric_report_definition.hpp
index a1231b1..6dce89f 100644
--- a/redfish-core/lib/metric_report_definition.hpp
+++ b/redfish-core/lib/metric_report_definition.hpp
@@ -1,10 +1,10 @@
 #pragma once
 
-#include "node.hpp"
 #include "sensors.hpp"
 #include "utils/telemetry_utils.hpp"
 #include "utils/time_utils.hpp"
 
+#include <app.hpp>
 #include <boost/container/flat_map.hpp>
 
 #include <tuple>
@@ -347,171 +347,140 @@
 };
 } // namespace telemetry
 
-class MetricReportDefinitionCollection : public Node
+inline void requestRoutesMetricReportDefinitionCollection(App& app)
 {
-  public:
-    MetricReportDefinitionCollection(App& app) :
-        Node(app, "/redfish/v1/TelemetryService/MetricReportDefinitions/")
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-    }
+    BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/MetricReportDefinitions/")
+        .privileges({"Login"})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                asyncResp->res.jsonValue["@odata.type"] =
+                    "#MetricReportDefinitionCollection."
+                    "MetricReportDefinitionCollection";
+                asyncResp->res.jsonValue["@odata.id"] =
+                    "/redfish/v1/TelemetryService/MetricReportDefinitions";
+                asyncResp->res.jsonValue["Name"] =
+                    "Metric Definition Collection";
 
-  private:
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&, const std::vector<std::string>&) override
-    {
-        asyncResp->res.jsonValue["@odata.type"] =
-            "#MetricReportDefinitionCollection."
-            "MetricReportDefinitionCollection";
-        asyncResp->res.jsonValue["@odata.id"] =
-            "/redfish/v1/TelemetryService/MetricReportDefinitions";
-        asyncResp->res.jsonValue["Name"] = "Metric Definition Collection";
+                telemetry::getReportCollection(
+                    asyncResp, telemetry::metricReportDefinitionUri);
+            });
 
-        telemetry::getReportCollection(asyncResp,
-                                       telemetry::metricReportDefinitionUri);
-    }
+    BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/MetricReportDefinitions/")
+        .privileges({"ConfigureManager"})
+        .methods(boost::beast::http::verb::post)(
+            [](const crow::Request& req,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                telemetry::AddReportArgs args;
+                if (!telemetry::getUserParameters(asyncResp->res, req, args))
+                {
+                    return;
+                }
 
-    void doPost(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                const crow::Request& req,
-                const std::vector<std::string>&) override
-    {
-        telemetry::AddReportArgs args;
-        if (!telemetry::getUserParameters(asyncResp->res, req, args))
-        {
-            return;
-        }
+                boost::container::flat_set<std::pair<std::string, std::string>>
+                    chassisSensors;
+                if (!telemetry::getChassisSensorNode(asyncResp, args.metrics,
+                                                     chassisSensors))
+                {
+                    return;
+                }
 
-        boost::container::flat_set<std::pair<std::string, std::string>>
-            chassisSensors;
-        if (!telemetry::getChassisSensorNode(asyncResp, args.metrics,
-                                             chassisSensors))
-        {
-            return;
-        }
+                auto addReportReq = std::make_shared<telemetry::AddReport>(
+                    std::move(args), asyncResp);
+                for (const auto& [chassis, sensorType] : chassisSensors)
+                {
+                    retrieveUriToDbusMap(
+                        chassis, sensorType,
+                        [asyncResp, addReportReq](
+                            const boost::beast::http::status status,
+                            const boost::container::flat_map<
+                                std::string, std::string>& uriToDbus) {
+                            if (status != boost::beast::http::status::ok)
+                            {
+                                BMCWEB_LOG_ERROR
+                                    << "Failed to retrieve URI to dbus "
+                                       "sensors map with err "
+                                    << static_cast<unsigned>(status);
+                                return;
+                            }
+                            addReportReq->insert(uriToDbus);
+                        });
+                }
+            });
+}
 
-        auto addReportReq =
-            std::make_shared<telemetry::AddReport>(std::move(args), asyncResp);
-        for (const auto& [chassis, sensorType] : chassisSensors)
-        {
-            retrieveUriToDbusMap(
-                chassis, sensorType,
-                [asyncResp, addReportReq](
-                    const boost::beast::http::status status,
-                    const boost::container::flat_map<std::string, std::string>&
-                        uriToDbus) {
-                    if (status != boost::beast::http::status::ok)
-                    {
-                        BMCWEB_LOG_ERROR << "Failed to retrieve URI to dbus "
-                                            "sensors map with err "
-                                         << static_cast<unsigned>(status);
-                        return;
-                    }
-                    addReportReq->insert(uriToDbus);
-                });
-        }
-    }
-};
-
-class MetricReportDefinition : public Node
+inline void requestRoutesMetricReportDefinition(App& app)
 {
-  public:
-    MetricReportDefinition(App& app) :
-        Node(app, "/redfish/v1/TelemetryService/MetricReportDefinitions/<str>/",
-             std::string())
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-    }
+    BMCWEB_ROUTE(app,
+                 "/redfish/v1/TelemetryService/MetricReportDefinitions/<str>/")
+        .privileges({"Login"})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+               const std::string& id) {
+                crow::connections::systemBus->async_method_call(
+                    [asyncResp, id](
+                        const boost::system::error_code ec,
+                        const std::vector<std::pair<
+                            std::string,
+                            std::variant<std::string, bool, uint64_t,
+                                         telemetry::ReadingParameters>>>& ret) {
+                        if (ec.value() == EBADR ||
+                            ec == boost::system::errc::host_unreachable)
+                        {
+                            messages::resourceNotFound(
+                                asyncResp->res, "MetricReportDefinition", id);
+                            return;
+                        }
+                        if (ec)
+                        {
+                            BMCWEB_LOG_ERROR << "respHandler DBus error " << ec;
+                            messages::internalError(asyncResp->res);
+                            return;
+                        }
 
-  private:
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&,
-               const std::vector<std::string>& params) override
-    {
+                        telemetry::fillReportDefinition(asyncResp, id, ret);
+                    },
+                    telemetry::service, telemetry::getDbusReportPath(id),
+                    "org.freedesktop.DBus.Properties", "GetAll",
+                    telemetry::reportInterface);
+            });
+    BMCWEB_ROUTE(app,
+                 "/redfish/v1/TelemetryService/MetricReportDefinitions/<str>/")
+        .privileges({"ConfigureManager"})
+        .methods(boost::beast::http::verb::delete_)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+               const std::string& id)
 
-        if (params.size() != 1)
-        {
-            messages::internalError(asyncResp->res);
-            return;
-        }
+            {
+                const std::string reportPath = telemetry::getDbusReportPath(id);
 
-        const std::string& id = params[0];
-        crow::connections::systemBus->async_method_call(
-            [asyncResp,
-             id](const boost::system::error_code ec,
-                 const std::vector<std::pair<
-                     std::string, std::variant<std::string, bool, uint64_t,
-                                               telemetry::ReadingParameters>>>&
-                     ret) {
-                if (ec.value() == EBADR ||
-                    ec == boost::system::errc::host_unreachable)
-                {
-                    messages::resourceNotFound(asyncResp->res,
-                                               "MetricReportDefinition", id);
-                    return;
-                }
-                if (ec)
-                {
-                    BMCWEB_LOG_ERROR << "respHandler DBus error " << ec;
-                    messages::internalError(asyncResp->res);
-                    return;
-                }
+                crow::connections::systemBus->async_method_call(
+                    [asyncResp, id](const boost::system::error_code ec) {
+                        /*
+                         * boost::system::errc and std::errc are missing value
+                         * for EBADR error that is defined in Linux.
+                         */
+                        if (ec.value() == EBADR)
+                        {
+                            messages::resourceNotFound(
+                                asyncResp->res, "MetricReportDefinition", id);
+                            return;
+                        }
 
-                telemetry::fillReportDefinition(asyncResp, id, ret);
-            },
-            telemetry::service, telemetry::getDbusReportPath(id),
-            "org.freedesktop.DBus.Properties", "GetAll",
-            telemetry::reportInterface);
-    }
+                        if (ec)
+                        {
+                            BMCWEB_LOG_ERROR << "respHandler DBus error " << ec;
+                            messages::internalError(asyncResp->res);
+                            return;
+                        }
 
-    void doDelete(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                  const crow::Request&,
-                  const std::vector<std::string>& params) override
-    {
-        if (params.size() != 1)
-        {
-            messages::internalError(asyncResp->res);
-            return;
-        }
-
-        const std::string& id = params[0];
-        const std::string reportPath = telemetry::getDbusReportPath(id);
-
-        crow::connections::systemBus->async_method_call(
-            [asyncResp, id](const boost::system::error_code ec) {
-                /*
-                 * boost::system::errc and std::errc are missing value for
-                 * EBADR error that is defined in Linux.
-                 */
-                if (ec.value() == EBADR)
-                {
-                    messages::resourceNotFound(asyncResp->res,
-                                               "MetricReportDefinition", id);
-                    return;
-                }
-
-                if (ec)
-                {
-                    BMCWEB_LOG_ERROR << "respHandler DBus error " << ec;
-                    messages::internalError(asyncResp->res);
-                    return;
-                }
-
-                asyncResp->res.result(boost::beast::http::status::no_content);
-            },
-            telemetry::service, reportPath, "xyz.openbmc_project.Object.Delete",
-            "Delete");
-    }
-};
+                        asyncResp->res.result(
+                            boost::beast::http::status::no_content);
+                    },
+                    telemetry::service, reportPath,
+                    "xyz.openbmc_project.Object.Delete", "Delete");
+            });
+}
 } // namespace redfish
diff --git a/redfish-core/lib/network_protocol.hpp b/redfish-core/lib/network_protocol.hpp
index 491204e..46b5405 100644
--- a/redfish-core/lib/network_protocol.hpp
+++ b/redfish-core/lib/network_protocol.hpp
@@ -16,9 +16,9 @@
 #pragma once
 
 #include "error_messages.hpp"
-#include "node.hpp"
 #include "openbmc_dbus_rest.hpp"
 
+#include <app.hpp>
 #include <utils/json_utils.hpp>
 
 #include <optional>
@@ -26,6 +26,9 @@
 namespace redfish
 {
 
+void getNTPProtocolEnabled(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp);
+std::string getHostName();
+
 enum NetworkProtocolUnitStructFields
 {
     NET_PROTO_UNIT_NAME,
@@ -125,428 +128,406 @@
         "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
 }
 
-class NetworkProtocol : public Node
+void getNetworkData(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
 {
-  public:
-    NetworkProtocol(App& app) :
-        Node(app, "/redfish/v1/Managers/bmc/NetworkProtocol/")
+    asyncResp->res.jsonValue["@odata.type"] =
+        "#ManagerNetworkProtocol.v1_5_0.ManagerNetworkProtocol";
+    asyncResp->res.jsonValue["@odata.id"] =
+        "/redfish/v1/Managers/bmc/NetworkProtocol";
+    asyncResp->res.jsonValue["Id"] = "NetworkProtocol";
+    asyncResp->res.jsonValue["Name"] = "Manager Network Protocol";
+    asyncResp->res.jsonValue["Description"] = "Manager Network Service";
+    asyncResp->res.jsonValue["Status"]["Health"] = "OK";
+    asyncResp->res.jsonValue["Status"]["HealthRollup"] = "OK";
+    asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
+
+    // HTTP is Mandatory attribute as per OCP Baseline Profile - v1.0.0,
+    // but from security perspective it is not recommended to use.
+    // Hence using protocolEnabled as false to make it OCP and security-wise
+    // compliant
+    asyncResp->res.jsonValue["HTTP"]["Port"] = 0;
+    asyncResp->res.jsonValue["HTTP"]["ProtocolEnabled"] = false;
+
+    for (auto& protocol : protocolToDBus)
     {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
+        asyncResp->res.jsonValue[protocol.first]["Port"] =
+            nlohmann::detail::value_t::null;
+        asyncResp->res.jsonValue[protocol.first]["ProtocolEnabled"] = false;
     }
 
-  private:
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&, const std::vector<std::string>&) override
-    {
-        getData(asyncResp);
-    }
+    std::string hostName = getHostName();
 
-    std::string getHostName() const
-    {
-        std::string hostName;
+    asyncResp->res.jsonValue["HostName"] = hostName;
 
-        std::array<char, HOST_NAME_MAX> hostNameCStr;
-        if (gethostname(hostNameCStr.data(), hostNameCStr.size()) == 0)
-        {
-            hostName = hostNameCStr.data();
-        }
-        return hostName;
-    }
+    getNTPProtocolEnabled(asyncResp);
 
-    void getNTPProtocolEnabled(
-        const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
-    {
-        crow::connections::systemBus->async_method_call(
-            [asyncResp](const boost::system::error_code errorCode,
-                        const std::variant<std::string>& timeSyncMethod) {
-                if (errorCode)
+    // TODO Get eth0 interface data, and call the below callback for JSON
+    // preparation
+    getEthernetIfaceData(
+        [hostName, asyncResp](const bool& success,
+                              const std::vector<std::string>& ntpServers,
+                              const std::vector<std::string>& domainNames) {
+            if (!success)
+            {
+                messages::resourceNotFound(asyncResp->res, "EthernetInterface",
+                                           "eth0");
+                return;
+            }
+            asyncResp->res.jsonValue["NTP"]["NTPServers"] = ntpServers;
+            if (hostName.empty() == false)
+            {
+                std::string fqdn = hostName;
+                if (domainNames.empty() == false)
                 {
-                    return;
+                    fqdn += ".";
+                    fqdn += domainNames[0];
+                }
+                asyncResp->res.jsonValue["FQDN"] = std::move(fqdn);
+            }
+        });
+
+    crow::connections::systemBus->async_method_call(
+        [asyncResp](const boost::system::error_code e,
+                    const std::vector<UnitStruct>& r) {
+            if (e)
+            {
+                asyncResp->res.jsonValue = nlohmann::json::object();
+                messages::internalError(asyncResp->res);
+                return;
+            }
+            asyncResp->res.jsonValue["HTTPS"]["Certificates"] = {
+                {"@odata.id", "/redfish/v1/Managers/bmc/NetworkProtocol/"
+                              "HTTPS/Certificates"}};
+
+            for (auto& unit : r)
+            {
+                /* Only traverse through <xyz>.socket units */
+                const std::string& unitName =
+                    std::get<NET_PROTO_UNIT_NAME>(unit);
+                if (!boost::ends_with(unitName, ".socket"))
+                {
+                    continue;
                 }
 
-                const std::string* s =
-                    std::get_if<std::string>(&timeSyncMethod);
-
-                if (*s == "xyz.openbmc_project.Time.Synchronization.Method.NTP")
+                for (auto& kv : protocolToDBus)
                 {
-                    asyncResp->res.jsonValue["NTP"]["ProtocolEnabled"] = true;
-                }
-                else if (*s == "xyz.openbmc_project.Time.Synchronization."
-                               "Method.Manual")
-                {
-                    asyncResp->res.jsonValue["NTP"]["ProtocolEnabled"] = false;
-                }
-            },
-            "xyz.openbmc_project.Settings",
-            "/xyz/openbmc_project/time/sync_method",
-            "org.freedesktop.DBus.Properties", "Get",
-            "xyz.openbmc_project.Time.Synchronization", "TimeSyncMethod");
-    }
-
-    void getData(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
-    {
-        asyncResp->res.jsonValue["@odata.type"] =
-            "#ManagerNetworkProtocol.v1_5_0.ManagerNetworkProtocol";
-        asyncResp->res.jsonValue["@odata.id"] =
-            "/redfish/v1/Managers/bmc/NetworkProtocol";
-        asyncResp->res.jsonValue["Id"] = "NetworkProtocol";
-        asyncResp->res.jsonValue["Name"] = "Manager Network Protocol";
-        asyncResp->res.jsonValue["Description"] = "Manager Network Service";
-        asyncResp->res.jsonValue["Status"]["Health"] = "OK";
-        asyncResp->res.jsonValue["Status"]["HealthRollup"] = "OK";
-        asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
-
-        // HTTP is Mandatory attribute as per OCP Baseline Profile - v1.0.0,
-        // but from security perspective it is not recommended to use.
-        // Hence using protocolEnabled as false to make it OCP and security-wise
-        // compliant
-        asyncResp->res.jsonValue["HTTP"]["Port"] = 0;
-        asyncResp->res.jsonValue["HTTP"]["ProtocolEnabled"] = false;
-
-        for (auto& protocol : protocolToDBus)
-        {
-            asyncResp->res.jsonValue[protocol.first]["Port"] =
-                nlohmann::detail::value_t::null;
-            asyncResp->res.jsonValue[protocol.first]["ProtocolEnabled"] = false;
-        }
-
-        std::string hostName = getHostName();
-
-        asyncResp->res.jsonValue["HostName"] = hostName;
-
-        getNTPProtocolEnabled(asyncResp);
-
-        // TODO Get eth0 interface data, and call the below callback for JSON
-        // preparation
-        getEthernetIfaceData(
-            [hostName, asyncResp](const bool& success,
-                                  const std::vector<std::string>& ntpServers,
-                                  const std::vector<std::string>& domainNames) {
-                if (!success)
-                {
-                    messages::resourceNotFound(asyncResp->res,
-                                               "EthernetInterface", "eth0");
-                    return;
-                }
-                asyncResp->res.jsonValue["NTP"]["NTPServers"] = ntpServers;
-                if (hostName.empty() == false)
-                {
-                    std::string fqdn = hostName;
-                    if (domainNames.empty() == false)
-                    {
-                        fqdn += ".";
-                        fqdn += domainNames[0];
-                    }
-                    asyncResp->res.jsonValue["FQDN"] = std::move(fqdn);
-                }
-            });
-
-        crow::connections::systemBus->async_method_call(
-            [asyncResp](const boost::system::error_code e,
-                        const std::vector<UnitStruct>& r) {
-                if (e)
-                {
-                    asyncResp->res.jsonValue = nlohmann::json::object();
-                    messages::internalError(asyncResp->res);
-                    return;
-                }
-                asyncResp->res.jsonValue["HTTPS"]["Certificates"] = {
-                    {"@odata.id", "/redfish/v1/Managers/bmc/NetworkProtocol/"
-                                  "HTTPS/Certificates"}};
-
-                for (auto& unit : r)
-                {
-                    /* Only traverse through <xyz>.socket units */
-                    const std::string& unitName =
-                        std::get<NET_PROTO_UNIT_NAME>(unit);
-                    if (!boost::ends_with(unitName, ".socket"))
+                    // We are interested in services, which starts with
+                    // mapped service name
+                    if (!boost::starts_with(unitName, kv.second))
                     {
                         continue;
                     }
+                    const char* rfServiceKey = kv.first;
+                    const std::string& socketPath =
+                        std::get<NET_PROTO_UNIT_OBJ_PATH>(unit);
+                    const std::string& unitState =
+                        std::get<NET_PROTO_UNIT_SUB_STATE>(unit);
 
-                    for (auto& kv : protocolToDBus)
-                    {
-                        // We are interested in services, which starts with
-                        // mapped service name
-                        if (!boost::starts_with(unitName, kv.second))
-                        {
-                            continue;
-                        }
-                        const char* rfServiceKey = kv.first;
-                        const std::string& socketPath =
-                            std::get<NET_PROTO_UNIT_OBJ_PATH>(unit);
-                        const std::string& unitState =
-                            std::get<NET_PROTO_UNIT_SUB_STATE>(unit);
+                    asyncResp->res.jsonValue[rfServiceKey]["ProtocolEnabled"] =
+                        (unitState == "running") || (unitState == "listening");
 
-                        asyncResp->res
-                            .jsonValue[rfServiceKey]["ProtocolEnabled"] =
-                            (unitState == "running") ||
-                            (unitState == "listening");
-
-                        crow::connections::systemBus->async_method_call(
-                            [asyncResp,
-                             rfServiceKey{std::string(rfServiceKey)}](
-                                const boost::system::error_code ec,
-                                const std::variant<std::vector<std::tuple<
-                                    std::string, std::string>>>& resp) {
-                                if (ec)
-                                {
-                                    messages::internalError(asyncResp->res);
-                                    return;
-                                }
-                                const std::vector<
-                                    std::tuple<std::string, std::string>>*
-                                    responsePtr = std::get_if<std::vector<
-                                        std::tuple<std::string, std::string>>>(
-                                        &resp);
-                                if (responsePtr == nullptr ||
-                                    responsePtr->size() < 1)
-                                {
-                                    return;
-                                }
-
-                                const std::string& listenStream =
-                                    std::get<NET_PROTO_LISTEN_STREAM>(
-                                        (*responsePtr)[0]);
-                                std::size_t lastColonPos =
-                                    listenStream.rfind(':');
-                                if (lastColonPos == std::string::npos)
-                                {
-                                    // Not a port
-                                    return;
-                                }
-                                std::string portStr =
-                                    listenStream.substr(lastColonPos + 1);
-                                if (portStr.empty())
-                                {
-                                    return;
-                                }
-                                char* endPtr = nullptr;
-                                errno = 0;
-                                // Use strtol instead of stroi to avoid
-                                // exceptions
-                                long port =
-                                    std::strtol(portStr.c_str(), &endPtr, 10);
-                                if ((errno == 0) && (*endPtr == '\0'))
-                                {
-                                    asyncResp->res
-                                        .jsonValue[rfServiceKey]["Port"] = port;
-                                }
+                    crow::connections::systemBus->async_method_call(
+                        [asyncResp, rfServiceKey{std::string(rfServiceKey)}](
+                            const boost::system::error_code ec,
+                            const std::variant<std::vector<
+                                std::tuple<std::string, std::string>>>& resp) {
+                            if (ec)
+                            {
+                                messages::internalError(asyncResp->res);
                                 return;
-                            },
-                            "org.freedesktop.systemd1", socketPath,
-                            "org.freedesktop.DBus.Properties", "Get",
-                            "org.freedesktop.systemd1.Socket", "Listen");
+                            }
+                            const std::vector<
+                                std::tuple<std::string, std::string>>*
+                                responsePtr = std::get_if<std::vector<
+                                    std::tuple<std::string, std::string>>>(
+                                    &resp);
+                            if (responsePtr == nullptr ||
+                                responsePtr->size() < 1)
+                            {
+                                return;
+                            }
 
-                        // We found service, break the inner loop.
-                        break;
-                    }
+                            const std::string& listenStream =
+                                std::get<NET_PROTO_LISTEN_STREAM>(
+                                    (*responsePtr)[0]);
+                            std::size_t lastColonPos = listenStream.rfind(':');
+                            if (lastColonPos == std::string::npos)
+                            {
+                                // Not a port
+                                return;
+                            }
+                            std::string portStr =
+                                listenStream.substr(lastColonPos + 1);
+                            if (portStr.empty())
+                            {
+                                return;
+                            }
+                            char* endPtr = nullptr;
+                            errno = 0;
+                            // Use strtol instead of stroi to avoid
+                            // exceptions
+                            long port =
+                                std::strtol(portStr.c_str(), &endPtr, 10);
+                            if ((errno == 0) && (*endPtr == '\0'))
+                            {
+                                asyncResp->res.jsonValue[rfServiceKey]["Port"] =
+                                    port;
+                            }
+                            return;
+                        },
+                        "org.freedesktop.systemd1", socketPath,
+                        "org.freedesktop.DBus.Properties", "Get",
+                        "org.freedesktop.systemd1.Socket", "Listen");
+
+                    // We found service, break the inner loop.
+                    break;
                 }
-            },
-            "org.freedesktop.systemd1", "/org/freedesktop/systemd1",
-            "org.freedesktop.systemd1.Manager", "ListUnits");
-    }
+            }
+        },
+        "org.freedesktop.systemd1", "/org/freedesktop/systemd1",
+        "org.freedesktop.systemd1.Manager", "ListUnits");
+}
 
 #ifdef BMCWEB_ALLOW_DEPRECATED_HOSTNAME_PATCH
-    void
-        handleHostnamePatch(const std::string& hostName,
-                            const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
-    {
-        crow::connections::systemBus->async_method_call(
-            [asyncResp](const boost::system::error_code ec) {
-                if (ec)
-                {
-                    messages::internalError(asyncResp->res);
-                    return;
-                }
-            },
-            "xyz.openbmc_project.Network",
-            "/xyz/openbmc_project/network/config",
-            "org.freedesktop.DBus.Properties", "Set",
-            "xyz.openbmc_project.Network.SystemConfiguration", "HostName",
-            std::variant<std::string>(hostName));
-    }
+void handleHostnamePatch(const std::string& hostName,
+                         const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+{
+    crow::connections::systemBus->async_method_call(
+        [asyncResp](const boost::system::error_code ec) {
+            if (ec)
+            {
+                messages::internalError(asyncResp->res);
+                return;
+            }
+        },
+        "xyz.openbmc_project.Network", "/xyz/openbmc_project/network/config",
+        "org.freedesktop.DBus.Properties", "Set",
+        "xyz.openbmc_project.Network.SystemConfiguration", "HostName",
+        std::variant<std::string>(hostName));
+}
 #endif
 
-    void handleNTPProtocolEnabled(
-        const bool& ntpEnabled,
-        const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+void handleNTPProtocolEnabled(
+    const bool& ntpEnabled, const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+{
+    std::string timeSyncMethod;
+    if (ntpEnabled)
     {
-        std::string timeSyncMethod;
-        if (ntpEnabled)
-        {
-            timeSyncMethod =
-                "xyz.openbmc_project.Time.Synchronization.Method.NTP";
-        }
-        else
-        {
-            timeSyncMethod =
-                "xyz.openbmc_project.Time.Synchronization.Method.Manual";
-        }
-
-        crow::connections::systemBus->async_method_call(
-            [asyncResp](const boost::system::error_code errorCode) {
-                if (errorCode)
-                {
-                    messages::internalError(asyncResp->res);
-                }
-            },
-            "xyz.openbmc_project.Settings",
-            "/xyz/openbmc_project/time/sync_method",
-            "org.freedesktop.DBus.Properties", "Set",
-            "xyz.openbmc_project.Time.Synchronization", "TimeSyncMethod",
-            std::variant<std::string>{timeSyncMethod});
+        timeSyncMethod = "xyz.openbmc_project.Time.Synchronization.Method.NTP";
+    }
+    else
+    {
+        timeSyncMethod =
+            "xyz.openbmc_project.Time.Synchronization.Method.Manual";
     }
 
-    void handleNTPServersPatch(
-        const std::vector<std::string>& ntpServers,
-        const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
-    {
-        crow::connections::systemBus->async_method_call(
-            [asyncResp](const boost::system::error_code ec) {
-                if (ec)
-                {
-                    messages::internalError(asyncResp->res);
-                    return;
-                }
-            },
-            "xyz.openbmc_project.Network", "/xyz/openbmc_project/network/eth0",
-            "org.freedesktop.DBus.Properties", "Set",
-            "xyz.openbmc_project.Network.EthernetInterface", "NTPServers",
-            std::variant<std::vector<std::string>>{ntpServers});
-    }
+    crow::connections::systemBus->async_method_call(
+        [asyncResp](const boost::system::error_code errorCode) {
+            if (errorCode)
+            {
+                messages::internalError(asyncResp->res);
+            }
+        },
+        "xyz.openbmc_project.Settings", "/xyz/openbmc_project/time/sync_method",
+        "org.freedesktop.DBus.Properties", "Set",
+        "xyz.openbmc_project.Time.Synchronization", "TimeSyncMethod",
+        std::variant<std::string>{timeSyncMethod});
+}
 
-    void handleIpmiProtocolEnabled(
-        const bool ipmiProtocolEnabled,
-        const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
-    {
-        crow::connections::systemBus->async_method_call(
-            [ipmiProtocolEnabled,
-             asyncResp](const boost::system::error_code ec,
-                        const crow::openbmc_mapper::GetSubTreeType& subtree) {
-                if (ec)
+void handleNTPServersPatch(const std::vector<std::string>& ntpServers,
+                           const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+{
+    crow::connections::systemBus->async_method_call(
+        [asyncResp](const boost::system::error_code ec) {
+            if (ec)
+            {
+                messages::internalError(asyncResp->res);
+                return;
+            }
+        },
+        "xyz.openbmc_project.Network", "/xyz/openbmc_project/network/eth0",
+        "org.freedesktop.DBus.Properties", "Set",
+        "xyz.openbmc_project.Network.EthernetInterface", "NTPServers",
+        std::variant<std::vector<std::string>>{ntpServers});
+}
+
+void handleIpmiProtocolEnabled(
+    const bool ipmiProtocolEnabled,
+    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+{
+    crow::connections::systemBus->async_method_call(
+        [ipmiProtocolEnabled,
+         asyncResp](const boost::system::error_code ec,
+                    const crow::openbmc_mapper::GetSubTreeType& subtree) {
+            if (ec)
+            {
+                messages::internalError(asyncResp->res);
+                return;
+            }
+
+            constexpr char const* netipmidBasePath =
+                "/xyz/openbmc_project/control/service/"
+                "phosphor_2dipmi_2dnet_40";
+
+            for (const auto& entry : subtree)
+            {
+                if (boost::algorithm::starts_with(entry.first,
+                                                  netipmidBasePath))
                 {
-                    messages::internalError(asyncResp->res);
+                    crow::connections::systemBus->async_method_call(
+                        [asyncResp](const boost::system::error_code ec2) {
+                            if (ec2)
+                            {
+                                messages::internalError(asyncResp->res);
+                                return;
+                            }
+                        },
+                        entry.second.begin()->first, entry.first,
+                        "org.freedesktop.DBus.Properties", "Set",
+                        "xyz.openbmc_project.Control.Service.Attributes",
+                        "Running", std::variant<bool>{ipmiProtocolEnabled});
+
+                    crow::connections::systemBus->async_method_call(
+                        [asyncResp](const boost::system::error_code ec2) {
+                            if (ec2)
+                            {
+                                messages::internalError(asyncResp->res);
+                                return;
+                            }
+                        },
+                        entry.second.begin()->first, entry.first,
+                        "org.freedesktop.DBus.Properties", "Set",
+                        "xyz.openbmc_project.Control.Service.Attributes",
+                        "Enabled", std::variant<bool>{ipmiProtocolEnabled});
+                }
+            }
+        },
+        "xyz.openbmc_project.ObjectMapper",
+        "/xyz/openbmc_project/object_mapper",
+        "xyz.openbmc_project.ObjectMapper", "GetSubTree",
+        "/xyz/openbmc_project/control/service", 0,
+        std::array<const char*, 1>{
+            "xyz.openbmc_project.Control.Service.Attributes"});
+}
+
+std::string getHostName()
+{
+    std::string hostName;
+
+    std::array<char, HOST_NAME_MAX> hostNameCStr;
+    if (gethostname(hostNameCStr.data(), hostNameCStr.size()) == 0)
+    {
+        hostName = hostNameCStr.data();
+    }
+    return hostName;
+}
+
+void getNTPProtocolEnabled(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+{
+    crow::connections::systemBus->async_method_call(
+        [asyncResp](const boost::system::error_code errorCode,
+                    const std::variant<std::string>& timeSyncMethod) {
+            if (errorCode)
+            {
+                return;
+            }
+
+            const std::string* s = std::get_if<std::string>(&timeSyncMethod);
+
+            if (*s == "xyz.openbmc_project.Time.Synchronization.Method.NTP")
+            {
+                asyncResp->res.jsonValue["NTP"]["ProtocolEnabled"] = true;
+            }
+            else if (*s == "xyz.openbmc_project.Time.Synchronization."
+                           "Method.Manual")
+            {
+                asyncResp->res.jsonValue["NTP"]["ProtocolEnabled"] = false;
+            }
+        },
+        "xyz.openbmc_project.Settings", "/xyz/openbmc_project/time/sync_method",
+        "org.freedesktop.DBus.Properties", "Get",
+        "xyz.openbmc_project.Time.Synchronization", "TimeSyncMethod");
+}
+
+inline void requestRoutesNetworkProtocol(App& app)
+{
+    BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/NetworkProtocol/")
+        .privileges({"ConfigureManager"})
+        .methods(boost::beast::http::verb::patch)(
+            [](const crow::Request& req,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                std::optional<std::string> newHostName;
+                std::optional<nlohmann::json> ntp;
+                std::optional<nlohmann::json> ipmi;
+
+                if (!json_util::readJson(req, asyncResp->res, "NTP", ntp,
+                                         "HostName", newHostName, "IPMI", ipmi))
+                {
                     return;
                 }
 
-                constexpr char const* netipmidBasePath =
-                    "/xyz/openbmc_project/control/service/"
-                    "phosphor_2dipmi_2dnet_40";
-
-                for (const auto& entry : subtree)
+                asyncResp->res.result(boost::beast::http::status::no_content);
+                if (newHostName)
                 {
-                    if (boost::algorithm::starts_with(entry.first,
-                                                      netipmidBasePath))
-                    {
-                        crow::connections::systemBus->async_method_call(
-                            [asyncResp](const boost::system::error_code ec2) {
-                                if (ec2)
-                                {
-                                    messages::internalError(asyncResp->res);
-                                    return;
-                                }
-                            },
-                            entry.second.begin()->first, entry.first,
-                            "org.freedesktop.DBus.Properties", "Set",
-                            "xyz.openbmc_project.Control.Service.Attributes",
-                            "Running", std::variant<bool>{ipmiProtocolEnabled});
-
-                        crow::connections::systemBus->async_method_call(
-                            [asyncResp](const boost::system::error_code ec2) {
-                                if (ec2)
-                                {
-                                    messages::internalError(asyncResp->res);
-                                    return;
-                                }
-                            },
-                            entry.second.begin()->first, entry.first,
-                            "org.freedesktop.DBus.Properties", "Set",
-                            "xyz.openbmc_project.Control.Service.Attributes",
-                            "Enabled", std::variant<bool>{ipmiProtocolEnabled});
-                    }
-                }
-            },
-            "xyz.openbmc_project.ObjectMapper",
-            "/xyz/openbmc_project/object_mapper",
-            "xyz.openbmc_project.ObjectMapper", "GetSubTree",
-            "/xyz/openbmc_project/control/service", 0,
-            std::array<const char*, 1>{
-                "xyz.openbmc_project.Control.Service.Attributes"});
-    }
-
-    void doPatch(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                 const crow::Request& req,
-                 const std::vector<std::string>&) override
-    {
-
-        std::optional<std::string> newHostName;
-        std::optional<nlohmann::json> ntp;
-        std::optional<nlohmann::json> ipmi;
-
-        if (!json_util::readJson(req, asyncResp->res, "NTP", ntp, "HostName",
-                                 newHostName, "IPMI", ipmi))
-        {
-            return;
-        }
-
-        asyncResp->res.result(boost::beast::http::status::no_content);
-        if (newHostName)
-        {
 #ifdef BMCWEB_ALLOW_DEPRECATED_HOSTNAME_PATCH
-            handleHostnamePatch(*newHostName, asyncResp);
+                    handleHostnamePatch(*newHostName, asyncResp);
 #else
-            messages::propertyNotWritable(asyncResp->res, "HostName");
+                    messages::propertyNotWritable(asyncResp->res, "HostName");
 #endif
-        }
+                }
 
-        if (ntp)
-        {
-            std::optional<std::vector<std::string>> ntpServers;
-            std::optional<bool> ntpEnabled;
-            if (!json_util::readJson(*ntp, asyncResp->res, "NTPServers",
-                                     ntpServers, "ProtocolEnabled", ntpEnabled))
-            {
-                return;
-            }
+                if (ntp)
+                {
+                    std::optional<std::vector<std::string>> ntpServers;
+                    std::optional<bool> ntpEnabled;
+                    if (!json_util::readJson(*ntp, asyncResp->res, "NTPServers",
+                                             ntpServers, "ProtocolEnabled",
+                                             ntpEnabled))
+                    {
+                        return;
+                    }
 
-            if (ntpEnabled)
-            {
-                handleNTPProtocolEnabled(*ntpEnabled, asyncResp);
-            }
+                    if (ntpEnabled)
+                    {
+                        handleNTPProtocolEnabled(*ntpEnabled, asyncResp);
+                    }
 
-            if (ntpServers)
-            {
-                std::sort((*ntpServers).begin(), (*ntpServers).end());
-                (*ntpServers)
-                    .erase(
-                        std::unique((*ntpServers).begin(), (*ntpServers).end()),
-                        (*ntpServers).end());
-                handleNTPServersPatch(*ntpServers, asyncResp);
-            }
-        }
+                    if (ntpServers)
+                    {
+                        std::sort((*ntpServers).begin(), (*ntpServers).end());
+                        (*ntpServers)
+                            .erase(std::unique((*ntpServers).begin(),
+                                               (*ntpServers).end()),
+                                   (*ntpServers).end());
+                        handleNTPServersPatch(*ntpServers, asyncResp);
+                    }
+                }
 
-        if (ipmi)
-        {
-            std::optional<bool> ipmiProtocolEnabled;
-            if (!json_util::readJson(*ipmi, asyncResp->res, "ProtocolEnabled",
-                                     ipmiProtocolEnabled))
-            {
-                return;
-            }
+                if (ipmi)
+                {
+                    std::optional<bool> ipmiProtocolEnabled;
+                    if (!json_util::readJson(*ipmi, asyncResp->res,
+                                             "ProtocolEnabled",
+                                             ipmiProtocolEnabled))
+                    {
+                        return;
+                    }
 
-            if (ipmiProtocolEnabled)
-            {
-                handleIpmiProtocolEnabled(*ipmiProtocolEnabled, asyncResp);
-            }
-        }
-    }
-};
+                    if (ipmiProtocolEnabled)
+                    {
+                        handleIpmiProtocolEnabled(*ipmiProtocolEnabled,
+                                                  asyncResp);
+                    }
+                }
+            });
+
+    BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/NetworkProtocol/")
+        .privileges({"Login"})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                getNetworkData(asyncResp);
+            });
+}
 
 } // namespace redfish
diff --git a/redfish-core/lib/pcie.hpp b/redfish-core/lib/pcie.hpp
index 35d20a5..15b2280 100644
--- a/redfish-core/lib/pcie.hpp
+++ b/redfish-core/lib/pcie.hpp
@@ -16,8 +16,7 @@
 
 #pragma once
 
-#include "node.hpp"
-
+#include <app.hpp>
 #include <boost/system/linux_error.hpp>
 
 namespace redfish
@@ -70,73 +69,201 @@
         std::string(pciePath) + "/", 1, std::array<std::string, 0>());
 }
 
-class SystemPCIeDeviceCollection : public Node
+inline void requestRoutesSystemPCIeDeviceCollection(App& app)
 {
-  public:
-    SystemPCIeDeviceCollection(App& app) :
-        Node(app, "/redfish/v1/Systems/system/PCIeDevices/")
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-    }
-
-  private:
     /**
      * Functions triggers appropriate requests on DBus
      */
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&, const std::vector<std::string>&) override
-    {
-        asyncResp->res.jsonValue = {
-            {"@odata.type", "#PCIeDeviceCollection.PCIeDeviceCollection"},
-            {"@odata.id", "/redfish/v1/Systems/system/PCIeDevices"},
-            {"Name", "PCIe Device Collection"},
-            {"Description", "Collection of PCIe Devices"},
-            {"Members", nlohmann::json::array()},
-            {"Members@odata.count", 0}};
-        getPCIeDeviceList(asyncResp, "Members");
-    }
-};
+    BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/PCIeDevices/")
+        .privileges({"Login"})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
 
-class SystemPCIeDevice : public Node
+            {
+                asyncResp->res.jsonValue = {
+                    {"@odata.type",
+                     "#PCIeDeviceCollection.PCIeDeviceCollection"},
+                    {"@odata.id", "/redfish/v1/Systems/system/PCIeDevices"},
+                    {"Name", "PCIe Device Collection"},
+                    {"Description", "Collection of PCIe Devices"},
+                    {"Members", nlohmann::json::array()},
+                    {"Members@odata.count", 0}};
+                getPCIeDeviceList(asyncResp, "Members");
+            });
+}
+
+inline void requestRoutesSystemPCIeDevice(App& app)
 {
-  public:
-    SystemPCIeDevice(App& app) :
-        Node(app, "/redfish/v1/Systems/system/PCIeDevices/<str>/",
-             std::string())
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-    }
+    BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/PCIeDevices/<str>/")
+        .privileges({"Login"})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+               const std::string& device)
 
-  private:
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&,
-               const std::vector<std::string>& params) override
-    {
-        if (params.size() != 1)
-        {
-            messages::internalError(asyncResp->res);
-            return;
-        }
-        const std::string& device = params[0];
+            {
+                auto getPCIeDeviceCallback = [asyncResp, device](
+                                                 const boost::system::error_code
+                                                     ec,
+                                                 boost::container::flat_map<
+                                                     std::string,
+                                                     std::variant<std::string>>&
+                                                     pcieDevProperties) {
+                    if (ec)
+                    {
+                        BMCWEB_LOG_DEBUG
+                            << "failed to get PCIe Device properties ec: "
+                            << ec.value() << ": " << ec.message();
+                        if (ec.value() ==
+                            boost::system::linux_error::bad_request_descriptor)
+                        {
+                            messages::resourceNotFound(asyncResp->res,
+                                                       "PCIeDevice", device);
+                        }
+                        else
+                        {
+                            messages::internalError(asyncResp->res);
+                        }
+                        return;
+                    }
 
-        auto getPCIeDeviceCallback =
-            [asyncResp,
-             device](const boost::system::error_code ec,
-                     boost::container::flat_map<std::string,
-                                                std::variant<std::string>>&
-                         pcieDevProperties) {
+                    asyncResp->res.jsonValue = {
+                        {"@odata.type", "#PCIeDevice.v1_4_0.PCIeDevice"},
+                        {"@odata.id",
+                         "/redfish/v1/Systems/system/PCIeDevices/" + device},
+                        {"Name", "PCIe Device"},
+                        {"Id", device}};
+
+                    if (std::string* property = std::get_if<std::string>(
+                            &pcieDevProperties["Manufacturer"]);
+                        property)
+                    {
+                        asyncResp->res.jsonValue["Manufacturer"] = *property;
+                    }
+
+                    if (std::string* property = std::get_if<std::string>(
+                            &pcieDevProperties["DeviceType"]);
+                        property)
+                    {
+                        asyncResp->res.jsonValue["DeviceType"] = *property;
+                    }
+
+                    asyncResp->res.jsonValue["PCIeFunctions"] = {
+                        {"@odata.id",
+                         "/redfish/v1/Systems/system/PCIeDevices/" + device +
+                             "/PCIeFunctions"}};
+                };
+                std::string escapedPath = std::string(pciePath) + "/" + device;
+                dbus::utility::escapePathForDbus(escapedPath);
+                crow::connections::systemBus->async_method_call(
+                    std::move(getPCIeDeviceCallback), pcieService, escapedPath,
+                    "org.freedesktop.DBus.Properties", "GetAll",
+                    pcieDeviceInterface);
+            });
+}
+
+inline void requestRoutesSystemPCIeFunctionCollection(App& app)
+{
+    /**
+     * Functions triggers appropriate requests on DBus
+     */
+    BMCWEB_ROUTE(app,
+                 "/redfish/v1/Systems/system/PCIeDevices/<str>/PCIeFunctions/")
+        .privileges({"Login"})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+               const std::string& device)
+
+            {
+                asyncResp->res.jsonValue = {
+                    {"@odata.type",
+                     "#PCIeFunctionCollection.PCIeFunctionCollection"},
+                    {"@odata.id", "/redfish/v1/Systems/system/PCIeDevices/" +
+                                      device + "/PCIeFunctions"},
+                    {"Name", "PCIe Function Collection"},
+                    {"Description",
+                     "Collection of PCIe Functions for PCIe Device " + device}};
+
+                auto getPCIeDeviceCallback = [asyncResp, device](
+                                                 const boost::system::error_code
+                                                     ec,
+                                                 boost::container::flat_map<
+                                                     std::string,
+                                                     std::variant<std::string>>&
+                                                     pcieDevProperties) {
+                    if (ec)
+                    {
+                        BMCWEB_LOG_DEBUG
+                            << "failed to get PCIe Device properties ec: "
+                            << ec.value() << ": " << ec.message();
+                        if (ec.value() ==
+                            boost::system::linux_error::bad_request_descriptor)
+                        {
+                            messages::resourceNotFound(asyncResp->res,
+                                                       "PCIeDevice", device);
+                        }
+                        else
+                        {
+                            messages::internalError(asyncResp->res);
+                        }
+                        return;
+                    }
+
+                    nlohmann::json& pcieFunctionList =
+                        asyncResp->res.jsonValue["Members"];
+                    pcieFunctionList = nlohmann::json::array();
+                    static constexpr const int maxPciFunctionNum = 8;
+                    for (int functionNum = 0; functionNum < maxPciFunctionNum;
+                         functionNum++)
+                    {
+                        // Check if this function exists by looking for a device
+                        // ID
+                        std::string devIDProperty =
+                            "Function" + std::to_string(functionNum) +
+                            "DeviceId";
+                        std::string* property = std::get_if<std::string>(
+                            &pcieDevProperties[devIDProperty]);
+                        if (property && !property->empty())
+                        {
+                            pcieFunctionList.push_back(
+                                {{"@odata.id",
+                                  "/redfish/v1/Systems/system/PCIeDevices/" +
+                                      device + "/PCIeFunctions/" +
+                                      std::to_string(functionNum)}});
+                        }
+                    }
+                    asyncResp->res.jsonValue["PCIeFunctions@odata.count"] =
+                        pcieFunctionList.size();
+                };
+                std::string escapedPath = std::string(pciePath) + "/" + device;
+                dbus::utility::escapePathForDbus(escapedPath);
+                crow::connections::systemBus->async_method_call(
+                    std::move(getPCIeDeviceCallback), pcieService, escapedPath,
+                    "org.freedesktop.DBus.Properties", "GetAll",
+                    pcieDeviceInterface);
+            });
+}
+
+inline void requestRoutesSystemPCIeFunction(App& app)
+{
+    BMCWEB_ROUTE(
+        app,
+        "/redfish/v1/Systems/system/PCIeDevices/<str>/PCIeFunctions/<str>/")
+        .privileges({"Login"})
+        .methods(
+            boost::beast::http::verb::get)([](const crow::Request&,
+                                              const std::shared_ptr<
+                                                  bmcweb::AsyncResp>& asyncResp,
+                                              const std::string& device,
+                                              const std::string& function) {
+            auto getPCIeDeviceCallback = [asyncResp, device, function](
+                                             const boost::system::error_code ec,
+                                             boost::container::flat_map<
+                                                 std::string,
+                                                 std::variant<std::string>>&
+                                                 pcieDevProperties) {
                 if (ec)
                 {
                     BMCWEB_LOG_DEBUG
@@ -155,274 +282,99 @@
                     return;
                 }
 
+                // Check if this function exists by looking for a device ID
+                std::string devIDProperty = "Function" + function + "DeviceId";
+                if (std::string* property = std::get_if<std::string>(
+                        &pcieDevProperties[devIDProperty]);
+                    property && property->empty())
+                {
+                    messages::resourceNotFound(asyncResp->res, "PCIeFunction",
+                                               function);
+                    return;
+                }
+
                 asyncResp->res.jsonValue = {
-                    {"@odata.type", "#PCIeDevice.v1_4_0.PCIeDevice"},
-                    {"@odata.id",
-                     "/redfish/v1/Systems/system/PCIeDevices/" + device},
-                    {"Name", "PCIe Device"},
-                    {"Id", device}};
-
-                if (std::string* property = std::get_if<std::string>(
-                        &pcieDevProperties["Manufacturer"]);
-                    property)
-                {
-                    asyncResp->res.jsonValue["Manufacturer"] = *property;
-                }
-
-                if (std::string* property = std::get_if<std::string>(
-                        &pcieDevProperties["DeviceType"]);
-                    property)
-                {
-                    asyncResp->res.jsonValue["DeviceType"] = *property;
-                }
-
-                asyncResp->res.jsonValue["PCIeFunctions"] = {
+                    {"@odata.type", "#PCIeFunction.v1_2_0.PCIeFunction"},
                     {"@odata.id", "/redfish/v1/Systems/system/PCIeDevices/" +
-                                      device + "/PCIeFunctions"}};
+                                      device + "/PCIeFunctions/" + function},
+                    {"Name", "PCIe Function"},
+                    {"Id", function},
+                    {"FunctionId", std::stoi(function)},
+                    {"Links",
+                     {{"PCIeDevice",
+                       {{"@odata.id",
+                         "/redfish/v1/Systems/system/PCIeDevices/" +
+                             device}}}}}};
+
+                if (std::string* property = std::get_if<std::string>(
+                        &pcieDevProperties["Function" + function + "DeviceId"]);
+                    property)
+                {
+                    asyncResp->res.jsonValue["DeviceId"] = *property;
+                }
+
+                if (std::string* property = std::get_if<std::string>(
+                        &pcieDevProperties["Function" + function + "VendorId"]);
+                    property)
+                {
+                    asyncResp->res.jsonValue["VendorId"] = *property;
+                }
+
+                if (std::string* property = std::get_if<std::string>(
+                        &pcieDevProperties["Function" + function +
+                                           "FunctionType"]);
+                    property)
+                {
+                    asyncResp->res.jsonValue["FunctionType"] = *property;
+                }
+
+                if (std::string* property = std::get_if<std::string>(
+                        &pcieDevProperties["Function" + function +
+                                           "DeviceClass"]);
+                    property)
+                {
+                    asyncResp->res.jsonValue["DeviceClass"] = *property;
+                }
+
+                if (std::string* property = std::get_if<std::string>(
+                        &pcieDevProperties["Function" + function +
+                                           "ClassCode"]);
+                    property)
+                {
+                    asyncResp->res.jsonValue["ClassCode"] = *property;
+                }
+
+                if (std::string* property = std::get_if<std::string>(
+                        &pcieDevProperties["Function" + function +
+                                           "RevisionId"]);
+                    property)
+                {
+                    asyncResp->res.jsonValue["RevisionId"] = *property;
+                }
+
+                if (std::string* property = std::get_if<std::string>(
+                        &pcieDevProperties["Function" + function +
+                                           "SubsystemId"]);
+                    property)
+                {
+                    asyncResp->res.jsonValue["SubsystemId"] = *property;
+                }
+
+                if (std::string* property = std::get_if<std::string>(
+                        &pcieDevProperties["Function" + function +
+                                           "SubsystemVendorId"]);
+                    property)
+                {
+                    asyncResp->res.jsonValue["SubsystemVendorId"] = *property;
+                }
             };
-        std::string escapedPath = std::string(pciePath) + "/" + device;
-        dbus::utility::escapePathForDbus(escapedPath);
-        crow::connections::systemBus->async_method_call(
-            std::move(getPCIeDeviceCallback), pcieService, escapedPath,
-            "org.freedesktop.DBus.Properties", "GetAll", pcieDeviceInterface);
-    }
-};
-
-class SystemPCIeFunctionCollection : public Node
-{
-  public:
-    SystemPCIeFunctionCollection(App& app) :
-        Node(app, "/redfish/v1/Systems/system/PCIeDevices/<str>/PCIeFunctions/",
-             std::string())
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-    }
-
-  private:
-    /**
-     * Functions triggers appropriate requests on DBus
-     */
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&,
-               const std::vector<std::string>& params) override
-    {
-        if (params.size() != 1)
-        {
-            messages::internalError(asyncResp->res);
-            return;
-        }
-        const std::string& device = params[0];
-        asyncResp->res.jsonValue = {
-            {"@odata.type", "#PCIeFunctionCollection.PCIeFunctionCollection"},
-            {"@odata.id", "/redfish/v1/Systems/system/PCIeDevices/" + device +
-                              "/PCIeFunctions"},
-            {"Name", "PCIe Function Collection"},
-            {"Description",
-             "Collection of PCIe Functions for PCIe Device " + device}};
-
-        auto getPCIeDeviceCallback =
-            [asyncResp,
-             device](const boost::system::error_code ec,
-                     boost::container::flat_map<std::string,
-                                                std::variant<std::string>>&
-                         pcieDevProperties) {
-                if (ec)
-                {
-                    BMCWEB_LOG_DEBUG
-                        << "failed to get PCIe Device properties ec: "
-                        << ec.value() << ": " << ec.message();
-                    if (ec.value() ==
-                        boost::system::linux_error::bad_request_descriptor)
-                    {
-                        messages::resourceNotFound(asyncResp->res, "PCIeDevice",
-                                                   device);
-                    }
-                    else
-                    {
-                        messages::internalError(asyncResp->res);
-                    }
-                    return;
-                }
-
-                nlohmann::json& pcieFunctionList =
-                    asyncResp->res.jsonValue["Members"];
-                pcieFunctionList = nlohmann::json::array();
-                static constexpr const int maxPciFunctionNum = 8;
-                for (int functionNum = 0; functionNum < maxPciFunctionNum;
-                     functionNum++)
-                {
-                    // Check if this function exists by looking for a device ID
-                    std::string devIDProperty =
-                        "Function" + std::to_string(functionNum) + "DeviceId";
-                    std::string* property = std::get_if<std::string>(
-                        &pcieDevProperties[devIDProperty]);
-                    if (property && !property->empty())
-                    {
-                        pcieFunctionList.push_back(
-                            {{"@odata.id",
-                              "/redfish/v1/Systems/system/PCIeDevices/" +
-                                  device + "/PCIeFunctions/" +
-                                  std::to_string(functionNum)}});
-                    }
-                }
-                asyncResp->res.jsonValue["PCIeFunctions@odata.count"] =
-                    pcieFunctionList.size();
-            };
-        std::string escapedPath = std::string(pciePath) + "/" + device;
-        dbus::utility::escapePathForDbus(escapedPath);
-        crow::connections::systemBus->async_method_call(
-            std::move(getPCIeDeviceCallback), pcieService, escapedPath,
-            "org.freedesktop.DBus.Properties", "GetAll", pcieDeviceInterface);
-    }
-};
-
-class SystemPCIeFunction : public Node
-{
-  public:
-    SystemPCIeFunction(App& app) :
-        Node(
-            app,
-            "/redfish/v1/Systems/system/PCIeDevices/<str>/PCIeFunctions/<str>/",
-            std::string(), std::string())
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-    }
-
-  private:
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&,
-               const std::vector<std::string>& params) override
-    {
-        if (params.size() != 2)
-        {
-            messages::internalError(asyncResp->res);
-            return;
-        }
-        const std::string& device = params[0];
-        const std::string& function = params[1];
-
-        auto getPCIeDeviceCallback = [asyncResp, device, function](
-                                         const boost::system::error_code ec,
-                                         boost::container::flat_map<
-                                             std::string,
-                                             std::variant<std::string>>&
-                                             pcieDevProperties) {
-            if (ec)
-            {
-                BMCWEB_LOG_DEBUG
-                    << "failed to get PCIe Device properties ec: " << ec.value()
-                    << ": " << ec.message();
-                if (ec.value() ==
-                    boost::system::linux_error::bad_request_descriptor)
-                {
-                    messages::resourceNotFound(asyncResp->res, "PCIeDevice",
-                                               device);
-                }
-                else
-                {
-                    messages::internalError(asyncResp->res);
-                }
-                return;
-            }
-
-            // Check if this function exists by looking for a device ID
-            std::string devIDProperty = "Function" + function + "DeviceId";
-            if (std::string* property =
-                    std::get_if<std::string>(&pcieDevProperties[devIDProperty]);
-                property && property->empty())
-            {
-                messages::resourceNotFound(asyncResp->res, "PCIeFunction",
-                                           function);
-                return;
-            }
-
-            asyncResp->res.jsonValue = {
-                {"@odata.type", "#PCIeFunction.v1_2_0.PCIeFunction"},
-                {"@odata.id", "/redfish/v1/Systems/system/PCIeDevices/" +
-                                  device + "/PCIeFunctions/" + function},
-                {"Name", "PCIe Function"},
-                {"Id", function},
-                {"FunctionId", std::stoi(function)},
-                {"Links",
-                 {{"PCIeDevice",
-                   {{"@odata.id",
-                     "/redfish/v1/Systems/system/PCIeDevices/" + device}}}}}};
-
-            if (std::string* property = std::get_if<std::string>(
-                    &pcieDevProperties["Function" + function + "DeviceId"]);
-                property)
-            {
-                asyncResp->res.jsonValue["DeviceId"] = *property;
-            }
-
-            if (std::string* property = std::get_if<std::string>(
-                    &pcieDevProperties["Function" + function + "VendorId"]);
-                property)
-            {
-                asyncResp->res.jsonValue["VendorId"] = *property;
-            }
-
-            if (std::string* property = std::get_if<std::string>(
-                    &pcieDevProperties["Function" + function + "FunctionType"]);
-                property)
-            {
-                asyncResp->res.jsonValue["FunctionType"] = *property;
-            }
-
-            if (std::string* property = std::get_if<std::string>(
-                    &pcieDevProperties["Function" + function + "DeviceClass"]);
-                property)
-            {
-                asyncResp->res.jsonValue["DeviceClass"] = *property;
-            }
-
-            if (std::string* property = std::get_if<std::string>(
-                    &pcieDevProperties["Function" + function + "ClassCode"]);
-                property)
-            {
-                asyncResp->res.jsonValue["ClassCode"] = *property;
-            }
-
-            if (std::string* property = std::get_if<std::string>(
-                    &pcieDevProperties["Function" + function + "RevisionId"]);
-                property)
-            {
-                asyncResp->res.jsonValue["RevisionId"] = *property;
-            }
-
-            if (std::string* property = std::get_if<std::string>(
-                    &pcieDevProperties["Function" + function + "SubsystemId"]);
-                property)
-            {
-                asyncResp->res.jsonValue["SubsystemId"] = *property;
-            }
-
-            if (std::string* property = std::get_if<std::string>(
-                    &pcieDevProperties["Function" + function +
-                                       "SubsystemVendorId"]);
-                property)
-            {
-                asyncResp->res.jsonValue["SubsystemVendorId"] = *property;
-            }
-        };
-        std::string escapedPath = std::string(pciePath) + "/" + device;
-        dbus::utility::escapePathForDbus(escapedPath);
-        crow::connections::systemBus->async_method_call(
-            std::move(getPCIeDeviceCallback), pcieService, escapedPath,
-            "org.freedesktop.DBus.Properties", "GetAll", pcieDeviceInterface);
-    }
-};
+            std::string escapedPath = std::string(pciePath) + "/" + device;
+            dbus::utility::escapePathForDbus(escapedPath);
+            crow::connections::systemBus->async_method_call(
+                std::move(getPCIeDeviceCallback), pcieService, escapedPath,
+                "org.freedesktop.DBus.Properties", "GetAll",
+                pcieDeviceInterface);
+        });
+}
 
 } // namespace redfish
diff --git a/redfish-core/lib/power.hpp b/redfish-core/lib/power.hpp
index 4173ce8..3cc0224 100644
--- a/redfish-core/lib/power.hpp
+++ b/redfish-core/lib/power.hpp
@@ -16,35 +16,19 @@
 */
 #pragma once
 
-#include "node.hpp"
 #include "sensors.hpp"
 
+#include <app.hpp>
+
 namespace redfish
 {
-
-class Power : public Node
+void setPowerCapOverride(
+    const std::shared_ptr<SensorsAsyncResp>& sensorsAsyncResp,
+    std::vector<nlohmann::json>& powerControlCollections)
 {
-  public:
-    Power(App& app) :
-        Node((app), "/redfish/v1/Chassis/<str>/Power/", std::string())
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-    }
-
-  private:
-    void setPowerCapOverride(
-        const std::shared_ptr<SensorsAsyncResp>& sensorsAsyncResp,
-        std::vector<nlohmann::json>& powerControlCollections)
-    {
-        auto getChassisPath = [sensorsAsyncResp, powerControlCollections](
-                                  const std::optional<std::string>&
-                                      chassisPath) mutable {
+    auto getChassisPath =
+        [sensorsAsyncResp, powerControlCollections](
+            const std::optional<std::string>& chassisPath) mutable {
             if (!chassisPath)
             {
                 BMCWEB_LOG_ERROR << "Don't find valid chassis path ";
@@ -138,235 +122,236 @@
                 "org.freedesktop.DBus.Properties", "Get",
                 "xyz.openbmc_project.Control.Power.Cap", "PowerCapEnable");
         };
-        getValidChassisPath(sensorsAsyncResp, std::move(getChassisPath));
-    }
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&,
-               const std::vector<std::string>& params) override
-    {
-        if (params.size() != 1)
-        {
-            asyncResp->res.result(
-                boost::beast::http::status::internal_server_error);
-            return;
-        }
-        const std::string& chassisName = params[0];
+    getValidChassisPath(sensorsAsyncResp, std::move(getChassisPath));
+}
+inline void requestRoutesPower(App& app)
+{
 
-        asyncResp->res.jsonValue["PowerControl"] = nlohmann::json::array();
+    BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/Power/")
+        .privileges({"Login"})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+               const std::string& chassisName) {
+                asyncResp->res.jsonValue["PowerControl"] =
+                    nlohmann::json::array();
 
-        auto sensorAsyncResp = std::make_shared<SensorsAsyncResp>(
-            asyncResp, chassisName,
-            sensors::dbus::paths.at(sensors::node::power),
-            sensors::node::power);
+                auto sensorAsyncResp = std::make_shared<SensorsAsyncResp>(
+                    asyncResp, chassisName,
+                    sensors::dbus::paths.at(sensors::node::power),
+                    sensors::node::power);
 
-        getChassisData(sensorAsyncResp);
+                getChassisData(sensorAsyncResp);
 
-        // This callback verifies that the power limit is only provided for the
-        // chassis that implements the Chassis inventory item. This prevents
-        // things like power supplies providing the chassis power limit
-        auto chassisHandler = [sensorAsyncResp](
-                                  const boost::system::error_code e,
-                                  const std::vector<std::string>&
-                                      chassisPaths) {
-            if (e)
-            {
-                BMCWEB_LOG_ERROR
-                    << "Power Limit GetSubTreePaths handler Dbus error " << e;
-                return;
-            }
-
-            bool found = false;
-            for (const std::string& chassis : chassisPaths)
-            {
-                size_t len = std::string::npos;
-                size_t lastPos = chassis.rfind('/');
-                if (lastPos == std::string::npos)
-                {
-                    continue;
-                }
-
-                if (lastPos == chassis.size() - 1)
-                {
-                    size_t end = lastPos;
-                    lastPos = chassis.rfind('/', lastPos - 1);
-                    if (lastPos == std::string::npos)
+                // This callback verifies that the power limit is only provided
+                // for the chassis that implements the Chassis inventory item.
+                // This prevents things like power supplies providing the
+                // chassis power limit
+                auto chassisHandler = [sensorAsyncResp](
+                                          const boost::system::error_code e,
+                                          const std::vector<std::string>&
+                                              chassisPaths) {
+                    if (e)
                     {
-                        continue;
-                    }
-
-                    len = end - (lastPos + 1);
-                }
-
-                std::string interfaceChassisName =
-                    chassis.substr(lastPos + 1, len);
-                if (!interfaceChassisName.compare(sensorAsyncResp->chassisId))
-                {
-                    found = true;
-                    break;
-                }
-            }
-
-            if (!found)
-            {
-                BMCWEB_LOG_DEBUG << "Power Limit not present for "
-                                 << sensorAsyncResp->chassisId;
-                return;
-            }
-
-            auto valueHandler =
-                [sensorAsyncResp](
-                    const boost::system::error_code ec,
-                    const std::vector<std::pair<std::string, SensorVariant>>&
-                        properties) {
-                    if (ec)
-                    {
-                        messages::internalError(
-                            sensorAsyncResp->asyncResp->res);
                         BMCWEB_LOG_ERROR
-                            << "Power Limit GetAll handler: Dbus error " << ec;
+                            << "Power Limit GetSubTreePaths handler Dbus error "
+                            << e;
                         return;
                     }
 
-                    nlohmann::json& tempArray = sensorAsyncResp->asyncResp->res
-                                                    .jsonValue["PowerControl"];
-
-                    // Put multiple "sensors" into a single PowerControl, 0, so
-                    // only create the first one
-                    if (tempArray.empty())
+                    bool found = false;
+                    for (const std::string& chassis : chassisPaths)
                     {
-                        // Mandatory properties odata.id and MemberId
-                        // A warning without a odata.type
-                        tempArray.push_back(
-                            {{"@odata.type", "#Power.v1_0_0.PowerControl"},
-                             {"@odata.id", "/redfish/v1/Chassis/" +
-                                               sensorAsyncResp->chassisId +
-                                               "/Power#/PowerControl/0"},
-                             {"Name", "Chassis Power Control"},
-                             {"MemberId", "0"}});
-                    }
-
-                    nlohmann::json& sensorJson = tempArray.back();
-                    bool enabled = false;
-                    double powerCap = 0.0;
-                    int64_t scale = 0;
-
-                    for (const std::pair<std::string, SensorVariant>& property :
-                         properties)
-                    {
-                        if (!property.first.compare("Scale"))
+                        size_t len = std::string::npos;
+                        size_t lastPos = chassis.rfind('/');
+                        if (lastPos == std::string::npos)
                         {
-                            const int64_t* i =
-                                std::get_if<int64_t>(&property.second);
-
-                            if (i)
-                            {
-                                scale = *i;
-                            }
+                            continue;
                         }
-                        else if (!property.first.compare("PowerCap"))
-                        {
-                            const double* d =
-                                std::get_if<double>(&property.second);
-                            const int64_t* i =
-                                std::get_if<int64_t>(&property.second);
-                            const uint32_t* u =
-                                std::get_if<uint32_t>(&property.second);
 
-                            if (d)
+                        if (lastPos == chassis.size() - 1)
+                        {
+                            size_t end = lastPos;
+                            lastPos = chassis.rfind('/', lastPos - 1);
+                            if (lastPos == std::string::npos)
                             {
-                                powerCap = *d;
+                                continue;
                             }
-                            else if (i)
-                            {
-                                powerCap = static_cast<double>(*i);
-                            }
-                            else if (u)
-                            {
-                                powerCap = *u;
-                            }
+
+                            len = end - (lastPos + 1);
                         }
-                        else if (!property.first.compare("PowerCapEnable"))
-                        {
-                            const bool* b = std::get_if<bool>(&property.second);
 
-                            if (b)
-                            {
-                                enabled = *b;
-                            }
+                        std::string interfaceChassisName =
+                            chassis.substr(lastPos + 1, len);
+                        if (!interfaceChassisName.compare(
+                                sensorAsyncResp->chassisId))
+                        {
+                            found = true;
+                            break;
                         }
                     }
 
-                    nlohmann::json& value =
-                        sensorJson["PowerLimit"]["LimitInWatts"];
-
-                    // LimitException is Mandatory attribute as per OCP Baseline
-                    // Profile – v1.0.0, so currently making it "NoAction"
-                    // as default value to make it OCP Compliant.
-                    sensorJson["PowerLimit"]["LimitException"] = "NoAction";
-
-                    if (enabled)
+                    if (!found)
                     {
-                        // Redfish specification indicates PowerLimit should be
-                        // null if the limit is not enabled.
-                        value = powerCap * std::pow(10, scale);
+                        BMCWEB_LOG_DEBUG << "Power Limit not present for "
+                                         << sensorAsyncResp->chassisId;
+                        return;
                     }
+
+                    auto valueHandler = [sensorAsyncResp](
+                                            const boost::system::error_code ec,
+                                            const std::vector<std::pair<
+                                                std::string, SensorVariant>>&
+                                                properties) {
+                        if (ec)
+                        {
+                            messages::internalError(
+                                sensorAsyncResp->asyncResp->res);
+                            BMCWEB_LOG_ERROR
+                                << "Power Limit GetAll handler: Dbus error "
+                                << ec;
+                            return;
+                        }
+
+                        nlohmann::json& tempArray =
+                            sensorAsyncResp->asyncResp->res
+                                .jsonValue["PowerControl"];
+
+                        // Put multiple "sensors" into a single PowerControl, 0,
+                        // so only create the first one
+                        if (tempArray.empty())
+                        {
+                            // Mandatory properties odata.id and MemberId
+                            // A warning without a odata.type
+                            tempArray.push_back(
+                                {{"@odata.type", "#Power.v1_0_0.PowerControl"},
+                                 {"@odata.id", "/redfish/v1/Chassis/" +
+                                                   sensorAsyncResp->chassisId +
+                                                   "/Power#/PowerControl/0"},
+                                 {"Name", "Chassis Power Control"},
+                                 {"MemberId", "0"}});
+                        }
+
+                        nlohmann::json& sensorJson = tempArray.back();
+                        bool enabled = false;
+                        double powerCap = 0.0;
+                        int64_t scale = 0;
+
+                        for (const std::pair<std::string, SensorVariant>&
+                                 property : properties)
+                        {
+                            if (!property.first.compare("Scale"))
+                            {
+                                const int64_t* i =
+                                    std::get_if<int64_t>(&property.second);
+
+                                if (i)
+                                {
+                                    scale = *i;
+                                }
+                            }
+                            else if (!property.first.compare("PowerCap"))
+                            {
+                                const double* d =
+                                    std::get_if<double>(&property.second);
+                                const int64_t* i =
+                                    std::get_if<int64_t>(&property.second);
+                                const uint32_t* u =
+                                    std::get_if<uint32_t>(&property.second);
+
+                                if (d)
+                                {
+                                    powerCap = *d;
+                                }
+                                else if (i)
+                                {
+                                    powerCap = static_cast<double>(*i);
+                                }
+                                else if (u)
+                                {
+                                    powerCap = *u;
+                                }
+                            }
+                            else if (!property.first.compare("PowerCapEnable"))
+                            {
+                                const bool* b =
+                                    std::get_if<bool>(&property.second);
+
+                                if (b)
+                                {
+                                    enabled = *b;
+                                }
+                            }
+                        }
+
+                        nlohmann::json& value =
+                            sensorJson["PowerLimit"]["LimitInWatts"];
+
+                        // LimitException is Mandatory attribute as per OCP
+                        // Baseline Profile – v1.0.0, so currently making it
+                        // "NoAction" as default value to make it OCP Compliant.
+                        sensorJson["PowerLimit"]["LimitException"] = "NoAction";
+
+                        if (enabled)
+                        {
+                            // Redfish specification indicates PowerLimit should
+                            // be null if the limit is not enabled.
+                            value = powerCap * std::pow(10, scale);
+                        }
+                    };
+
+                    crow::connections::systemBus->async_method_call(
+                        std::move(valueHandler), "xyz.openbmc_project.Settings",
+                        "/xyz/openbmc_project/control/host0/power_cap",
+                        "org.freedesktop.DBus.Properties", "GetAll",
+                        "xyz.openbmc_project.Control.Power.Cap");
                 };
 
-            crow::connections::systemBus->async_method_call(
-                std::move(valueHandler), "xyz.openbmc_project.Settings",
-                "/xyz/openbmc_project/control/host0/power_cap",
-                "org.freedesktop.DBus.Properties", "GetAll",
-                "xyz.openbmc_project.Control.Power.Cap");
-        };
+                crow::connections::systemBus->async_method_call(
+                    std::move(chassisHandler),
+                    "xyz.openbmc_project.ObjectMapper",
+                    "/xyz/openbmc_project/object_mapper",
+                    "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths",
+                    "/xyz/openbmc_project/inventory", 0,
+                    std::array<const char*, 2>{
+                        "xyz.openbmc_project.Inventory.Item.Board",
+                        "xyz.openbmc_project.Inventory.Item.Chassis"});
+            });
 
-        crow::connections::systemBus->async_method_call(
-            std::move(chassisHandler), "xyz.openbmc_project.ObjectMapper",
-            "/xyz/openbmc_project/object_mapper",
-            "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths",
-            "/xyz/openbmc_project/inventory", 0,
-            std::array<const char*, 2>{
-                "xyz.openbmc_project.Inventory.Item.Board",
-                "xyz.openbmc_project.Inventory.Item.Chassis"});
-    }
-    void doPatch(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                 const crow::Request& req,
-                 const std::vector<std::string>& params) override
-    {
-        if (params.size() != 1)
-        {
-            messages::internalError(asyncResp->res);
-            return;
-        }
+    BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/Power/")
+        .privileges({"ConfigureManager"})
+        .methods(boost::beast::http::verb::patch)(
+            [](const crow::Request& req,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+               const std::string& chassisName) {
+                auto sensorAsyncResp = std::make_shared<SensorsAsyncResp>(
+                    asyncResp, chassisName,
+                    sensors::dbus::paths.at(sensors::node::power),
+                    sensors::node::power);
 
-        const std::string& chassisName = params[0];
+                std::optional<std::vector<nlohmann::json>> voltageCollections;
+                std::optional<std::vector<nlohmann::json>> powerCtlCollections;
 
-        auto sensorAsyncResp = std::make_shared<SensorsAsyncResp>(
-            asyncResp, chassisName,
-            sensors::dbus::paths.at(sensors::node::power),
-            sensors::node::power);
+                if (!json_util::readJson(req, sensorAsyncResp->asyncResp->res,
+                                         "PowerControl", powerCtlCollections,
+                                         "Voltages", voltageCollections))
+                {
+                    return;
+                }
 
-        std::optional<std::vector<nlohmann::json>> voltageCollections;
-        std::optional<std::vector<nlohmann::json>> powerCtlCollections;
-
-        if (!json_util::readJson(req, sensorAsyncResp->asyncResp->res,
-                                 "PowerControl", powerCtlCollections,
-                                 "Voltages", voltageCollections))
-        {
-            return;
-        }
-
-        if (powerCtlCollections)
-        {
-            setPowerCapOverride(sensorAsyncResp, *powerCtlCollections);
-        }
-        if (voltageCollections)
-        {
-            std::unordered_map<std::string, std::vector<nlohmann::json>>
-                allCollections;
-            allCollections.emplace("Voltages", *std::move(voltageCollections));
-            checkAndDoSensorsOverride(sensorAsyncResp, allCollections);
-        }
-    }
-};
+                if (powerCtlCollections)
+                {
+                    setPowerCapOverride(sensorAsyncResp, *powerCtlCollections);
+                }
+                if (voltageCollections)
+                {
+                    std::unordered_map<std::string, std::vector<nlohmann::json>>
+                        allCollections;
+                    allCollections.emplace("Voltages",
+                                           *std::move(voltageCollections));
+                    checkAndDoSensorsOverride(sensorAsyncResp, allCollections);
+                }
+            });
+}
 
 } // namespace redfish
diff --git a/redfish-core/lib/processor.hpp b/redfish-core/lib/processor.hpp
index 49e04e2..8127510 100644
--- a/redfish-core/lib/processor.hpp
+++ b/redfish-core/lib/processor.hpp
@@ -17,8 +17,8 @@
 
 #include "health.hpp"
 
+#include <app.hpp>
 #include <boost/container/flat_map.hpp>
-#include <node.hpp>
 #include <sdbusplus/message/native_types.hpp>
 #include <sdbusplus/utility/dedup_variant.hpp>
 #include <utils/collection.hpp>
@@ -981,281 +981,212 @@
         std::variant<sdbusplus::message::object_path>(std::move(configPath)));
 }
 
-class OperatingConfigCollection : public Node
+inline void requestRoutesOperatingConfigCollection(App& app)
 {
-  public:
-    OperatingConfigCollection(App& app) :
-        Node(app,
-             "/redfish/v1/Systems/system/Processors/<str>/OperatingConfigs/",
-             std::string())
-    {
-        // Defined by Redfish spec privilege registry
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
-    }
 
-  private:
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request& req,
-               const std::vector<std::string>& params) override
-    {
-        if (params.size() != 1)
-        {
-            messages::internalError(asyncResp->res);
-            return;
-        }
+    BMCWEB_ROUTE(
+        app, "/redfish/v1/Systems/system/Processors/<str>/OperatingConfigs/")
+        .privileges({"Login"})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request& req,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+               const std::string& cpuName) {
+                asyncResp->res.jsonValue["@odata.type"] =
+                    "#OperatingConfigCollection.OperatingConfigCollection";
+                asyncResp->res.jsonValue["@odata.id"] = req.url;
+                asyncResp->res.jsonValue["Name"] =
+                    "Operating Config Collection";
 
-        const std::string& cpuName = params[0];
-        asyncResp->res.jsonValue["@odata.type"] =
-            "#OperatingConfigCollection.OperatingConfigCollection";
-        asyncResp->res.jsonValue["@odata.id"] = req.url;
-        asyncResp->res.jsonValue["Name"] = "Operating Config Collection";
+                // First find the matching CPU object so we know how to
+                // constrain our search for related Config objects.
+                crow::connections::systemBus->async_method_call(
+                    [asyncResp,
+                     cpuName](const boost::system::error_code ec,
+                              const std::vector<std::string>& objects) {
+                        if (ec)
+                        {
+                            BMCWEB_LOG_WARNING << "D-Bus error: " << ec << ", "
+                                               << ec.message();
+                            messages::internalError(asyncResp->res);
+                            return;
+                        }
 
-        // First find the matching CPU object so we know how to constrain our
-        // search for related Config objects.
-        crow::connections::systemBus->async_method_call(
-            [asyncResp, cpuName](const boost::system::error_code ec,
-                                 const std::vector<std::string>& objects) {
-                if (ec)
-                {
-                    BMCWEB_LOG_WARNING << "D-Bus error: " << ec << ", "
-                                       << ec.message();
-                    messages::internalError(asyncResp->res);
-                    return;
-                }
+                        for (const std::string& object : objects)
+                        {
+                            if (!boost::ends_with(object, cpuName))
+                            {
+                                continue;
+                            }
 
-                for (const std::string& object : objects)
-                {
-                    if (!boost::ends_with(object, cpuName))
+                            // Not expected that there will be multiple matching
+                            // CPU objects, but if there are just use the first
+                            // one.
+
+                            // Use the common search routine to construct the
+                            // Collection of all Config objects under this CPU.
+                            collection_util::getCollectionMembers(
+                                asyncResp,
+                                "/redfish/v1/Systems/system/Processors/" +
+                                    cpuName + "/OperatingConfigs",
+                                {"xyz.openbmc_project.Inventory.Item.Cpu."
+                                 "OperatingConfig"},
+                                object.c_str());
+                            return;
+                        }
+                    },
+                    "xyz.openbmc_project.ObjectMapper",
+                    "/xyz/openbmc_project/object_mapper",
+                    "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths",
+                    "/xyz/openbmc_project/inventory", 0,
+                    std::array<const char*, 1>{
+                        "xyz.openbmc_project.Control.Processor."
+                        "CurrentOperatingConfig"});
+            });
+}
+
+inline void requestRoutesOperatingConfig(App& app)
+{
+    BMCWEB_ROUTE(
+        app,
+        "/redfish/v1/Systems/system/Processors/<str>/OperatingConfigs/<str>/")
+        .privileges({"Login"})
+        .methods(
+            boost::beast::http::verb::get)([](const crow::Request& req,
+                                              const std::shared_ptr<
+                                                  bmcweb::AsyncResp>& asyncResp,
+                                              const std::string& cpuName,
+                                              const std::string& configName) {
+            // Ask for all objects implementing OperatingConfig so we can search
+            // for one with a matching name
+            crow::connections::systemBus->async_method_call(
+                [asyncResp, cpuName, configName,
+                 reqUrl{req.url}](boost::system::error_code ec,
+                                  const MapperGetSubTreeResponse& subtree) {
+                    if (ec)
                     {
-                        continue;
+                        BMCWEB_LOG_WARNING << "D-Bus error: " << ec << ", "
+                                           << ec.message();
+                        messages::internalError(asyncResp->res);
+                        return;
                     }
-
-                    // Not expected that there will be multiple matching CPU
-                    // objects, but if there are just use the first one.
-
-                    // Use the common search routine to construct the Collection
-                    // of all Config objects under this CPU.
-                    collection_util::getCollectionMembers(
-                        asyncResp,
-                        "/redfish/v1/Systems/system/Processors/" + cpuName +
-                            "/OperatingConfigs",
-                        {"xyz.openbmc_project.Inventory.Item.Cpu."
-                         "OperatingConfig"},
-                        object.c_str());
-                    return;
-                }
-            },
-            "xyz.openbmc_project.ObjectMapper",
-            "/xyz/openbmc_project/object_mapper",
-            "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths",
-            "/xyz/openbmc_project/inventory", 0,
-            std::array<const char*, 1>{"xyz.openbmc_project.Control.Processor."
-                                       "CurrentOperatingConfig"});
-    }
-};
-
-class OperatingConfig : public Node
-{
-  public:
-    OperatingConfig(App& app) :
-        Node(app,
-             "/redfish/v1/Systems/system/Processors/<str>/OperatingConfigs/"
-             "<str>/",
-             std::string(), std::string())
-    {
-        // Defined by Redfish spec privilege registry
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
-    }
-
-  private:
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request& req,
-               const std::vector<std::string>& params) override
-    {
-        if (params.size() != 2)
-        {
-            messages::internalError(asyncResp->res);
-            return;
-        }
-
-        const std::string& cpuName = params[0];
-        const std::string& configName = params[1];
-
-        // Ask for all objects implementing OperatingConfig so we can search for
-        // one with a matching name
-        crow::connections::systemBus->async_method_call(
-            [asyncResp, cpuName, configName,
-             reqUrl{req.url}](boost::system::error_code ec,
-                              const MapperGetSubTreeResponse& subtree) {
-                if (ec)
-                {
-                    BMCWEB_LOG_WARNING << "D-Bus error: " << ec << ", "
-                                       << ec.message();
-                    messages::internalError(asyncResp->res);
-                    return;
-                }
-                const std::string expectedEnding = cpuName + '/' + configName;
-                for (const auto& [objectPath, serviceMap] : subtree)
-                {
-                    // Ignore any configs without matching cpuX/configY
-                    if (!boost::ends_with(objectPath, expectedEnding) ||
-                        serviceMap.empty())
+                    const std::string expectedEnding =
+                        cpuName + '/' + configName;
+                    for (const auto& [objectPath, serviceMap] : subtree)
                     {
-                        continue;
+                        // Ignore any configs without matching cpuX/configY
+                        if (!boost::ends_with(objectPath, expectedEnding) ||
+                            serviceMap.empty())
+                        {
+                            continue;
+                        }
+
+                        nlohmann::json& json = asyncResp->res.jsonValue;
+                        json["@odata.type"] =
+                            "#OperatingConfig.v1_0_0.OperatingConfig";
+                        json["@odata.id"] = reqUrl;
+                        json["Name"] = "Processor Profile";
+                        json["Id"] = configName;
+
+                        // Just use the first implementation of the object - not
+                        // expected that there would be multiple matching
+                        // services
+                        getOperatingConfigData(
+                            asyncResp, serviceMap.begin()->first, objectPath);
+                        return;
                     }
+                    messages::resourceNotFound(asyncResp->res,
+                                               "OperatingConfig", configName);
+                },
+                "xyz.openbmc_project.ObjectMapper",
+                "/xyz/openbmc_project/object_mapper",
+                "xyz.openbmc_project.ObjectMapper", "GetSubTree",
+                "/xyz/openbmc_project/inventory", 0,
+                std::array<const char*, 1>{
+                    "xyz.openbmc_project.Inventory.Item.Cpu.OperatingConfig"});
+        });
+}
 
-                    nlohmann::json& json = asyncResp->res.jsonValue;
-                    json["@odata.type"] =
-                        "#OperatingConfig.v1_0_0.OperatingConfig";
-                    json["@odata.id"] = reqUrl;
-                    json["Name"] = "Processor Profile";
-                    json["Id"] = configName;
-
-                    // Just use the first implementation of the object - not
-                    // expected that there would be multiple matching services
-                    getOperatingConfigData(asyncResp, serviceMap.begin()->first,
-                                           objectPath);
-                    return;
-                }
-                messages::resourceNotFound(asyncResp->res, "OperatingConfig",
-                                           configName);
-            },
-            "xyz.openbmc_project.ObjectMapper",
-            "/xyz/openbmc_project/object_mapper",
-            "xyz.openbmc_project.ObjectMapper", "GetSubTree",
-            "/xyz/openbmc_project/inventory", 0,
-            std::array<const char*, 1>{
-                "xyz.openbmc_project.Inventory.Item.Cpu.OperatingConfig"});
-    }
-};
-
-class ProcessorCollection : public Node
+inline void requestRoutesProcessorCollection(App& app)
 {
-  public:
-    /*
-     * Default Constructor
-     */
-    ProcessorCollection(App& app) :
-        Node(app, "/redfish/v1/Systems/system/Processors/")
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
-    }
-
-  private:
     /**
      * Functions triggers appropriate requests on DBus
      */
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&, const std::vector<std::string>&) override
-    {
-        asyncResp->res.jsonValue["@odata.type"] =
-            "#ProcessorCollection.ProcessorCollection";
-        asyncResp->res.jsonValue["Name"] = "Processor Collection";
+    BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/Processors/")
+        .privileges({"Login"})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                asyncResp->res.jsonValue["@odata.type"] =
+                    "#ProcessorCollection.ProcessorCollection";
+                asyncResp->res.jsonValue["Name"] = "Processor Collection";
 
-        asyncResp->res.jsonValue["@odata.id"] =
-            "/redfish/v1/Systems/system/Processors";
+                asyncResp->res.jsonValue["@odata.id"] =
+                    "/redfish/v1/Systems/system/Processors";
 
-        collection_util::getCollectionMembers(
-            asyncResp, "/redfish/v1/Systems/system/Processors",
-            std::vector<const char*>(processorInterfaces.begin(),
-                                     processorInterfaces.end()));
-    }
-};
+                collection_util::getCollectionMembers(
+                    asyncResp, "/redfish/v1/Systems/system/Processors",
+                    std::vector<const char*>(processorInterfaces.begin(),
+                                             processorInterfaces.end()));
+            });
+}
 
-class Processor : public Node
+inline void requestRoutesProcessor(App& app)
 {
-  public:
-    /*
-     * Default Constructor
-     */
-    Processor(App& app) :
-        Node(app, "/redfish/v1/Systems/system/Processors/<str>/", std::string())
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
-    }
-
-  private:
     /**
      * Functions triggers appropriate requests on DBus
      */
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&,
-               const std::vector<std::string>& params) override
-    {
-        // Check if there is required param, truly entering this shall be
-        // impossible
-        if (params.size() != 1)
-        {
-            messages::internalError(asyncResp->res);
-            return;
-        }
-        const std::string& processorId = params[0];
-        asyncResp->res.jsonValue["@odata.type"] =
-            "#Processor.v1_11_0.Processor";
-        asyncResp->res.jsonValue["@odata.id"] =
-            "/redfish/v1/Systems/system/Processors/" + processorId;
 
-        getProcessorObject(asyncResp, processorId, getProcessorData);
-    }
+    BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/Processors/<str>/")
+        .privileges({"Login"})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+               const std::string& processorId) {
+                asyncResp->res.jsonValue["@odata.type"] =
+                    "#Processor.v1_11_0.Processor";
+                asyncResp->res.jsonValue["@odata.id"] =
+                    "/redfish/v1/Systems/system/Processors/" + processorId;
 
-    void doPatch(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                 const crow::Request& req,
-                 const std::vector<std::string>& params) override
-    {
-        std::optional<nlohmann::json> appliedConfigJson;
-        if (!json_util::readJson(req, asyncResp->res, "AppliedOperatingConfig",
-                                 appliedConfigJson))
-        {
-            return;
-        }
+                getProcessorObject(asyncResp, processorId, getProcessorData);
+            });
 
-        std::string appliedConfigUri;
-        if (appliedConfigJson)
-        {
-            if (!json_util::readJson(*appliedConfigJson, asyncResp->res,
-                                     "@odata.id", appliedConfigUri))
-            {
-                return;
-            }
-            // Check for 404 and find matching D-Bus object, then run property
-            // patch handlers if that all succeeds.
-            getProcessorObject(
-                asyncResp, params[0],
-                [appliedConfigUri = std::move(appliedConfigUri)](
-                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                    const std::string& processorId,
-                    const std::string& objectPath,
-                    const MapperServiceMap& serviceMap) {
-                    patchAppliedOperatingConfig(asyncResp, processorId,
-                                                appliedConfigUri, objectPath,
-                                                serviceMap);
-                });
-        }
-    }
-};
+    BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/Processors/<str>/")
+        .privileges({"ConfigureComponents"})
+        .methods(boost::beast::http::verb::patch)(
+            [](const crow::Request& req,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+               const std::string& processorId) {
+                std::optional<nlohmann::json> appliedConfigJson;
+                if (!json_util::readJson(req, asyncResp->res,
+                                         "AppliedOperatingConfig",
+                                         appliedConfigJson))
+                {
+                    return;
+                }
+
+                std::string appliedConfigUri;
+                if (appliedConfigJson)
+                {
+                    if (!json_util::readJson(*appliedConfigJson, asyncResp->res,
+                                             "@odata.id", appliedConfigUri))
+                    {
+                        return;
+                    }
+                    // Check for 404 and find matching D-Bus object, then run
+                    // property patch handlers if that all succeeds.
+                    getProcessorObject(
+                        asyncResp, processorId,
+                        [appliedConfigUri = std::move(appliedConfigUri)](
+                            const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+                            const std::string& processorId,
+                            const std::string& objectPath,
+                            const MapperServiceMap& serviceMap) {
+                            patchAppliedOperatingConfig(asyncResp, processorId,
+                                                        appliedConfigUri,
+                                                        objectPath, serviceMap);
+                        });
+                }
+            });
+}
 
 } // namespace redfish
diff --git a/redfish-core/lib/redfish_sessions.hpp b/redfish-core/lib/redfish_sessions.hpp
index bef2753..3ae75ea 100644
--- a/redfish-core/lib/redfish_sessions.hpp
+++ b/redfish-core/lib/redfish_sessions.hpp
@@ -19,6 +19,8 @@
 #include "node.hpp"
 #include "persistent_data.hpp"
 
+#include <app.hpp>
+
 namespace redfish
 {
 
diff --git a/redfish-core/lib/redfish_util.hpp b/redfish-core/lib/redfish_util.hpp
index 620e977..5494a23 100644
--- a/redfish-core/lib/redfish_util.hpp
+++ b/redfish-core/lib/redfish_util.hpp
@@ -16,8 +16,6 @@
 #ifndef BMCWEB_ENABLE_REDFISH_ONE_CHASSIS
 #pragma once
 
-#include <node.hpp>
-
 namespace redfish
 {
 
diff --git a/redfish-core/lib/roles.hpp b/redfish-core/lib/roles.hpp
index 8e00d43..b375ff0 100644
--- a/redfish-core/lib/roles.hpp
+++ b/redfish-core/lib/roles.hpp
@@ -15,7 +15,7 @@
 */
 #pragma once
 
-#include "node.hpp"
+#include <app.hpp>
 
 #include <variant>
 
@@ -70,114 +70,86 @@
     return true;
 }
 
-class Roles : public Node
+inline void requestRoutesRoles(App& app)
 {
-  public:
-    Roles(App& app) :
-        Node(app, "/redfish/v1/AccountService/Roles/<str>/", std::string())
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-    }
+    BMCWEB_ROUTE(app, "/redfish/v1/AccountService/Roles/<str>/")
+        .privileges({"Login"})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+               const std::string& roleId) {
+                nlohmann::json privArray = nlohmann::json::array();
+                if (false == getAssignedPrivFromRole(roleId, privArray))
+                {
+                    messages::resourceNotFound(asyncResp->res, "Role", roleId);
 
-  private:
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&,
-               const std::vector<std::string>& params) override
-    {
-        if (params.size() != 1)
-        {
-            messages::internalError(asyncResp->res);
+                    return;
+                }
 
-            return;
-        }
-        const std::string& roleId = params[0];
-        nlohmann::json privArray = nlohmann::json::array();
-        if (false == getAssignedPrivFromRole(roleId, privArray))
-        {
-            messages::resourceNotFound(asyncResp->res, "Role", roleId);
+                asyncResp->res.jsonValue = {
+                    {"@odata.type", "#Role.v1_2_2.Role"},
+                    {"Name", "User Role"},
+                    {"Description", roleId + " User Role"},
+                    {"OemPrivileges", nlohmann::json::array()},
+                    {"IsPredefined", true},
+                    {"Id", roleId},
+                    {"RoleId", roleId},
+                    {"@odata.id", "/redfish/v1/AccountService/Roles/" + roleId},
+                    {"AssignedPrivileges", std::move(privArray)}};
+            });
+}
 
-            return;
-        }
-
-        asyncResp->res.jsonValue = {
-            {"@odata.type", "#Role.v1_2_2.Role"},
-            {"Name", "User Role"},
-            {"Description", roleId + " User Role"},
-            {"OemPrivileges", nlohmann::json::array()},
-            {"IsPredefined", true},
-            {"Id", roleId},
-            {"RoleId", roleId},
-            {"@odata.id", "/redfish/v1/AccountService/Roles/" + roleId},
-            {"AssignedPrivileges", std::move(privArray)}};
-    }
-};
-
-class RoleCollection : public Node
+inline void requestRoutesRoleCollection(App& app)
 {
-  public:
-    RoleCollection(App& app) : Node(app, "/redfish/v1/AccountService/Roles/")
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-    }
+    BMCWEB_ROUTE(app, "/redfish/v1/AccountService/Roles/")
+        .privileges({"Login"})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                asyncResp->res.jsonValue = {
+                    {"@odata.id", "/redfish/v1/AccountService/Roles"},
+                    {"@odata.type", "#RoleCollection.RoleCollection"},
+                    {"Name", "Roles Collection"},
+                    {"Description", "BMC User Roles"}};
 
-  private:
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&, const std::vector<std::string>&) override
-    {
-
-        asyncResp->res.jsonValue = {
-            {"@odata.id", "/redfish/v1/AccountService/Roles"},
-            {"@odata.type", "#RoleCollection.RoleCollection"},
-            {"Name", "Roles Collection"},
-            {"Description", "BMC User Roles"}};
-
-        crow::connections::systemBus->async_method_call(
-            [asyncResp](const boost::system::error_code ec,
+                crow::connections::systemBus->async_method_call(
+                    [asyncResp](
+                        const boost::system::error_code ec,
                         const std::variant<std::vector<std::string>>& resp) {
-                if (ec)
-                {
-                    messages::internalError(asyncResp->res);
-                    return;
-                }
-                nlohmann::json& memberArray =
-                    asyncResp->res.jsonValue["Members"];
-                memberArray = nlohmann::json::array();
-                const std::vector<std::string>* privList =
-                    std::get_if<std::vector<std::string>>(&resp);
-                if (privList == nullptr)
-                {
-                    messages::internalError(asyncResp->res);
-                    return;
-                }
-                for (const std::string& priv : *privList)
-                {
-                    std::string role = getRoleFromPrivileges(priv);
-                    if (!role.empty())
-                    {
-                        memberArray.push_back(
-                            {{"@odata.id",
-                              "/redfish/v1/AccountService/Roles/" + role}});
-                    }
-                }
-                asyncResp->res.jsonValue["Members@odata.count"] =
-                    memberArray.size();
-            },
-            "xyz.openbmc_project.User.Manager", "/xyz/openbmc_project/user",
-            "org.freedesktop.DBus.Properties", "Get",
-            "xyz.openbmc_project.User.Manager", "AllPrivileges");
-    }
-};
+                        if (ec)
+                        {
+                            messages::internalError(asyncResp->res);
+                            return;
+                        }
+                        nlohmann::json& memberArray =
+                            asyncResp->res.jsonValue["Members"];
+                        memberArray = nlohmann::json::array();
+                        const std::vector<std::string>* privList =
+                            std::get_if<std::vector<std::string>>(&resp);
+                        if (privList == nullptr)
+                        {
+                            messages::internalError(asyncResp->res);
+                            return;
+                        }
+                        for (const std::string& priv : *privList)
+                        {
+                            std::string role = getRoleFromPrivileges(priv);
+                            if (!role.empty())
+                            {
+                                memberArray.push_back(
+                                    {{"@odata.id",
+                                      "/redfish/v1/AccountService/Roles/" +
+                                          role}});
+                            }
+                        }
+                        asyncResp->res.jsonValue["Members@odata.count"] =
+                            memberArray.size();
+                    },
+                    "xyz.openbmc_project.User.Manager",
+                    "/xyz/openbmc_project/user",
+                    "org.freedesktop.DBus.Properties", "Get",
+                    "xyz.openbmc_project.User.Manager", "AllPrivileges");
+            });
+}
 
 } // namespace redfish
diff --git a/redfish-core/lib/sensors.hpp b/redfish-core/lib/sensors.hpp
index b20f7eb..0fc7e70 100644
--- a/redfish-core/lib/sensors.hpp
+++ b/redfish-core/lib/sensors.hpp
@@ -15,8 +15,7 @@
 */
 #pragma once
 
-#include "node.hpp"
-
+#include <app.hpp>
 #include <boost/algorithm/string/predicate.hpp>
 #include <boost/algorithm/string/split.hpp>
 #include <boost/container/flat_map.hpp>
@@ -3106,177 +3105,142 @@
     getChassisData(resp);
 }
 
-class SensorCollection : public Node
+inline void requestRoutesSensorCollection(App& app)
 {
-  public:
-    SensorCollection(App& app) :
-        Node(app, "/redfish/v1/Chassis/<str>/Sensors/", std::string())
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-    }
+    BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/Sensors/")
+        .privileges({"Login"})
+        .methods(
+            boost::beast::http::verb::get)([](const crow::Request&,
+                                              const std::shared_ptr<
+                                                  bmcweb::AsyncResp>& aResp,
+                                              const std::string& chassisId) {
+            BMCWEB_LOG_DEBUG << "SensorCollection doGet enter";
 
-  private:
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
-               const crow::Request&,
-               const std::vector<std::string>& params) override
-    {
-        BMCWEB_LOG_DEBUG << "SensorCollection doGet enter";
-        if (params.size() != 1)
-        {
-            BMCWEB_LOG_DEBUG << "SensorCollection doGet param size < 1";
-            messages::internalError(aResp->res);
+            std::shared_ptr<SensorsAsyncResp> asyncResp =
+                std::make_shared<SensorsAsyncResp>(
+                    aResp, chassisId,
+                    sensors::dbus::paths.at(sensors::node::sensors),
+                    sensors::node::sensors);
 
-            return;
-        }
+            auto getChassisCb =
+                [asyncResp](
+                    const std::shared_ptr<
+                        boost::container::flat_set<std::string>>& sensorNames) {
+                    BMCWEB_LOG_DEBUG << "getChassisCb enter";
 
-        const std::string& chassisId = params[0];
-        std::shared_ptr<SensorsAsyncResp> asyncResp =
-            std::make_shared<SensorsAsyncResp>(
-                aResp, chassisId,
-                sensors::dbus::paths.at(sensors::node::sensors),
-                sensors::node::sensors);
-
-        auto getChassisCb =
-            [asyncResp](
-                const std::shared_ptr<boost::container::flat_set<std::string>>&
-                    sensorNames) {
-                BMCWEB_LOG_DEBUG << "getChassisCb enter";
-
-                nlohmann::json& entriesArray =
-                    asyncResp->asyncResp->res.jsonValue["Members"];
-                for (auto& sensor : *sensorNames)
-                {
-                    BMCWEB_LOG_DEBUG << "Adding sensor: " << sensor;
-
-                    sdbusplus::message::object_path path(sensor);
-                    std::string sensorName = path.filename();
-                    if (sensorName.empty())
+                    nlohmann::json& entriesArray =
+                        asyncResp->asyncResp->res.jsonValue["Members"];
+                    for (auto& sensor : *sensorNames)
                     {
-                        BMCWEB_LOG_ERROR << "Invalid sensor path: " << sensor;
-                        messages::internalError(asyncResp->asyncResp->res);
-                        return;
-                    }
-                    entriesArray.push_back(
-                        {{"@odata.id",
-                          "/redfish/v1/Chassis/" + asyncResp->chassisId + "/" +
-                              asyncResp->chassisSubNode + "/" + sensorName}});
-                }
+                        BMCWEB_LOG_DEBUG << "Adding sensor: " << sensor;
 
-                asyncResp->asyncResp->res.jsonValue["Members@odata.count"] =
-                    entriesArray.size();
-                BMCWEB_LOG_DEBUG << "getChassisCb exit";
-            };
-
-        // Get set of sensors in chassis
-        getChassis(asyncResp, std::move(getChassisCb));
-        BMCWEB_LOG_DEBUG << "SensorCollection doGet exit";
-    }
-};
-
-class Sensor : public Node
-{
-  public:
-    Sensor(App& app) :
-        Node(app, "/redfish/v1/Chassis/<str>/Sensors/<str>/", std::string(),
-             std::string())
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-    }
-
-  private:
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
-               const crow::Request&,
-               const std::vector<std::string>& params) override
-    {
-        BMCWEB_LOG_DEBUG << "Sensor doGet enter";
-        if (params.size() != 2)
-        {
-            BMCWEB_LOG_DEBUG << "Sensor doGet param size < 2";
-            messages::internalError(aResp->res);
-
-            return;
-        }
-        const std::string& chassisId = params[0];
-        std::shared_ptr<SensorsAsyncResp> asyncResp =
-            std::make_shared<SensorsAsyncResp>(aResp, chassisId,
-                                               std::vector<const char*>(),
-                                               sensors::node::sensors);
-
-        const std::string& sensorName = params[1];
-        const std::array<const char*, 1> interfaces = {
-            "xyz.openbmc_project.Sensor.Value"};
-
-        // Get a list of all of the sensors that implement Sensor.Value
-        // and get the path and service name associated with the sensor
-        crow::connections::systemBus->async_method_call(
-            [asyncResp, sensorName](const boost::system::error_code ec,
-                                    const GetSubTreeType& subtree) {
-                BMCWEB_LOG_DEBUG << "respHandler1 enter";
-                if (ec)
-                {
-                    messages::internalError(asyncResp->asyncResp->res);
-                    BMCWEB_LOG_ERROR << "Sensor getSensorPaths resp_handler: "
-                                     << "Dbus error " << ec;
-                    return;
-                }
-
-                GetSubTreeType::const_iterator it = std::find_if(
-                    subtree.begin(), subtree.end(),
-                    [sensorName](
-                        const std::pair<
-                            std::string,
-                            std::vector<std::pair<std::string,
-                                                  std::vector<std::string>>>>&
-                            object) {
-                        sdbusplus::message::object_path path(object.first);
-                        std::string name = path.filename();
-                        if (name.empty())
+                        sdbusplus::message::object_path path(sensor);
+                        std::string sensorName = path.filename();
+                        if (sensorName.empty())
                         {
                             BMCWEB_LOG_ERROR << "Invalid sensor path: "
-                                             << object.first;
-                            return false;
+                                             << sensor;
+                            messages::internalError(asyncResp->asyncResp->res);
+                            return;
                         }
+                        entriesArray.push_back(
+                            {{"@odata.id", "/redfish/v1/Chassis/" +
+                                               asyncResp->chassisId + "/" +
+                                               asyncResp->chassisSubNode + "/" +
+                                               sensorName}});
+                    }
 
-                        return name == sensorName;
-                    });
+                    asyncResp->asyncResp->res.jsonValue["Members@odata.count"] =
+                        entriesArray.size();
+                    BMCWEB_LOG_DEBUG << "getChassisCb exit";
+                };
 
-                if (it == subtree.end())
-                {
-                    BMCWEB_LOG_ERROR << "Could not find path for sensor: "
-                                     << sensorName;
-                    messages::resourceNotFound(asyncResp->asyncResp->res,
-                                               "Sensor", sensorName);
-                    return;
-                }
-                std::string_view sensorPath = (*it).first;
-                BMCWEB_LOG_DEBUG << "Found sensor path for sensor '"
-                                 << sensorName << "': " << sensorPath;
+            // Get set of sensors in chassis
+            getChassis(asyncResp, std::move(getChassisCb));
+            BMCWEB_LOG_DEBUG << "SensorCollection doGet exit";
+        });
+}
 
-                const std::shared_ptr<boost::container::flat_set<std::string>>
-                    sensorList = std::make_shared<
-                        boost::container::flat_set<std::string>>();
+inline void requestRoutesSensor(App& app)
+{
+    BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/Sensors/<str>/")
+        .privileges({"Login"})
+        .methods(
+            boost::beast::http::verb::get)([](const crow::Request&,
+                                              const std::shared_ptr<
+                                                  bmcweb::AsyncResp>& aResp,
+                                              const std::string& chassisId,
+                                              const std::string& sensorName) {
+            BMCWEB_LOG_DEBUG << "Sensor doGet enter";
+            std::shared_ptr<SensorsAsyncResp> asyncResp =
+                std::make_shared<SensorsAsyncResp>(aResp, chassisId,
+                                                   std::vector<const char*>(),
+                                                   sensors::node::sensors);
 
-                sensorList->emplace(sensorPath);
-                processSensorList(asyncResp, sensorList);
-                BMCWEB_LOG_DEBUG << "respHandler1 exit";
-            },
-            "xyz.openbmc_project.ObjectMapper",
-            "/xyz/openbmc_project/object_mapper",
-            "xyz.openbmc_project.ObjectMapper", "GetSubTree",
-            "/xyz/openbmc_project/sensors", 2, interfaces);
-    }
-};
+            const std::array<const char*, 1> interfaces = {
+                "xyz.openbmc_project.Sensor.Value"};
+
+            // Get a list of all of the sensors that implement Sensor.Value
+            // and get the path and service name associated with the sensor
+            crow::connections::systemBus->async_method_call(
+                [asyncResp, sensorName](const boost::system::error_code ec,
+                                        const GetSubTreeType& subtree) {
+                    BMCWEB_LOG_DEBUG << "respHandler1 enter";
+                    if (ec)
+                    {
+                        messages::internalError(asyncResp->asyncResp->res);
+                        BMCWEB_LOG_ERROR
+                            << "Sensor getSensorPaths resp_handler: "
+                            << "Dbus error " << ec;
+                        return;
+                    }
+
+                    GetSubTreeType::const_iterator it = std::find_if(
+                        subtree.begin(), subtree.end(),
+                        [sensorName](
+                            const std::pair<
+                                std::string,
+                                std::vector<std::pair<
+                                    std::string, std::vector<std::string>>>>&
+                                object) {
+                            sdbusplus::message::object_path path(object.first);
+                            std::string name = path.filename();
+                            if (name.empty())
+                            {
+                                BMCWEB_LOG_ERROR << "Invalid sensor path: "
+                                                 << object.first;
+                                return false;
+                            }
+
+                            return name == sensorName;
+                        });
+
+                    if (it == subtree.end())
+                    {
+                        BMCWEB_LOG_ERROR << "Could not find path for sensor: "
+                                         << sensorName;
+                        messages::resourceNotFound(asyncResp->asyncResp->res,
+                                                   "Sensor", sensorName);
+                        return;
+                    }
+                    std::string_view sensorPath = (*it).first;
+                    BMCWEB_LOG_DEBUG << "Found sensor path for sensor '"
+                                     << sensorName << "': " << sensorPath;
+
+                    const std::shared_ptr<
+                        boost::container::flat_set<std::string>>
+                        sensorList = std::make_shared<
+                            boost::container::flat_set<std::string>>();
+
+                    sensorList->emplace(sensorPath);
+                    processSensorList(asyncResp, sensorList);
+                    BMCWEB_LOG_DEBUG << "respHandler1 exit";
+                },
+                "xyz.openbmc_project.ObjectMapper",
+                "/xyz/openbmc_project/object_mapper",
+                "xyz.openbmc_project.ObjectMapper", "GetSubTree",
+                "/xyz/openbmc_project/sensors", 2, interfaces);
+        });
+}
 
 } // namespace redfish
diff --git a/redfish-core/lib/service_root.hpp b/redfish-core/lib/service_root.hpp
index 06f9c84..df3e8d5 100644
--- a/redfish-core/lib/service_root.hpp
+++ b/redfish-core/lib/service_root.hpp
@@ -15,71 +15,57 @@
 */
 #pragma once
 
-#include "node.hpp"
-
+#include <app.hpp>
 #include <utils/systemd_utils.hpp>
 
 namespace redfish
 {
 
-class ServiceRoot : public Node
+inline void requestRoutesServiceRoot(App& app)
 {
-  public:
-    ServiceRoot(App& app) : Node(app, "/redfish/v1/")
-    {
-        uuid = persistent_data::getConfig().systemUuid;
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {}},
-            {boost::beast::http::verb::head, {}},
-            {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
-    }
+    std::string uuid = persistent_data::getConfig().systemUuid;
+    BMCWEB_ROUTE(app, "/redfish/v1/")
+        .privileges({})
+        .methods(boost::beast::http::verb::get)(
+            [uuid](const crow::Request&,
+                   const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                asyncResp->res.jsonValue["@odata.type"] =
+                    "#ServiceRoot.v1_5_0.ServiceRoot";
+                asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1";
+                asyncResp->res.jsonValue["Id"] = "RootService";
+                asyncResp->res.jsonValue["Name"] = "Root Service";
+                asyncResp->res.jsonValue["RedfishVersion"] = "1.9.0";
+                asyncResp->res.jsonValue["Links"]["Sessions"] = {
+                    {"@odata.id", "/redfish/v1/SessionService/Sessions"}};
+                asyncResp->res.jsonValue["AccountService"] = {
+                    {"@odata.id", "/redfish/v1/AccountService"}};
+                asyncResp->res.jsonValue["Chassis"] = {
+                    {"@odata.id", "/redfish/v1/Chassis"}};
+                asyncResp->res.jsonValue["JsonSchemas"] = {
+                    {"@odata.id", "/redfish/v1/JsonSchemas"}};
+                asyncResp->res.jsonValue["Managers"] = {
+                    {"@odata.id", "/redfish/v1/Managers"}};
+                asyncResp->res.jsonValue["SessionService"] = {
+                    {"@odata.id", "/redfish/v1/SessionService"}};
+                asyncResp->res.jsonValue["Managers"] = {
+                    {"@odata.id", "/redfish/v1/Managers"}};
+                asyncResp->res.jsonValue["Systems"] = {
+                    {"@odata.id", "/redfish/v1/Systems"}};
+                asyncResp->res.jsonValue["Registries"] = {
+                    {"@odata.id", "/redfish/v1/Registries"}};
 
-  private:
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&, const std::vector<std::string>&) override
-    {
-        asyncResp->res.jsonValue["@odata.type"] =
-            "#ServiceRoot.v1_5_0.ServiceRoot";
-        asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1";
-        asyncResp->res.jsonValue["Id"] = "RootService";
-        asyncResp->res.jsonValue["Name"] = "Root Service";
-        asyncResp->res.jsonValue["RedfishVersion"] = "1.9.0";
-        asyncResp->res.jsonValue["Links"]["Sessions"] = {
-            {"@odata.id", "/redfish/v1/SessionService/Sessions"}};
-        asyncResp->res.jsonValue["AccountService"] = {
-            {"@odata.id", "/redfish/v1/AccountService"}};
-        asyncResp->res.jsonValue["Chassis"] = {
-            {"@odata.id", "/redfish/v1/Chassis"}};
-        asyncResp->res.jsonValue["JsonSchemas"] = {
-            {"@odata.id", "/redfish/v1/JsonSchemas"}};
-        asyncResp->res.jsonValue["Managers"] = {
-            {"@odata.id", "/redfish/v1/Managers"}};
-        asyncResp->res.jsonValue["SessionService"] = {
-            {"@odata.id", "/redfish/v1/SessionService"}};
-        asyncResp->res.jsonValue["Managers"] = {
-            {"@odata.id", "/redfish/v1/Managers"}};
-        asyncResp->res.jsonValue["Systems"] = {
-            {"@odata.id", "/redfish/v1/Systems"}};
-        asyncResp->res.jsonValue["Registries"] = {
-            {"@odata.id", "/redfish/v1/Registries"}};
-
-        asyncResp->res.jsonValue["UpdateService"] = {
-            {"@odata.id", "/redfish/v1/UpdateService"}};
-        asyncResp->res.jsonValue["UUID"] = uuid;
-        asyncResp->res.jsonValue["CertificateService"] = {
-            {"@odata.id", "/redfish/v1/CertificateService"}};
-        asyncResp->res.jsonValue["Tasks"] = {
-            {"@odata.id", "/redfish/v1/TaskService"}};
-        asyncResp->res.jsonValue["EventService"] = {
-            {"@odata.id", "/redfish/v1/EventService"}};
-        asyncResp->res.jsonValue["TelemetryService"] = {
-            {"@odata.id", "/redfish/v1/TelemetryService"}};
-    }
-
-    std::string uuid;
-};
+                asyncResp->res.jsonValue["UpdateService"] = {
+                    {"@odata.id", "/redfish/v1/UpdateService"}};
+                asyncResp->res.jsonValue["UUID"] = uuid;
+                asyncResp->res.jsonValue["CertificateService"] = {
+                    {"@odata.id", "/redfish/v1/CertificateService"}};
+                asyncResp->res.jsonValue["Tasks"] = {
+                    {"@odata.id", "/redfish/v1/TaskService"}};
+                asyncResp->res.jsonValue["EventService"] = {
+                    {"@odata.id", "/redfish/v1/EventService"}};
+                asyncResp->res.jsonValue["TelemetryService"] = {
+                    {"@odata.id", "/redfish/v1/TelemetryService"}};
+            });
+}
 
 } // namespace redfish
diff --git a/redfish-core/lib/storage.hpp b/redfish-core/lib/storage.hpp
index 34ef39a..0c3d9fd 100644
--- a/redfish-core/lib/storage.hpp
+++ b/redfish-core/lib/storage.hpp
@@ -18,197 +18,325 @@
 #include "health.hpp"
 #include "openbmc_dbus_rest.hpp"
 
-#include <node.hpp>
+#include <app.hpp>
 
 namespace redfish
 {
-class StorageCollection : public Node
+inline void requestRoutesStorageCollection(App& app)
 {
-  public:
-    StorageCollection(App& app) :
-        Node(app, "/redfish/v1/Systems/system/Storage/")
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
-    }
+    BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/Storage/")
+        .privileges({"Login"})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                asyncResp->res.jsonValue["@odata.type"] =
+                    "#StorageCollection.StorageCollection";
+                asyncResp->res.jsonValue["@odata.id"] =
+                    "/redfish/v1/Systems/system/Storage";
+                asyncResp->res.jsonValue["Name"] = "Storage Collection";
+                asyncResp->res.jsonValue["Members"] = {
+                    {{"@odata.id", "/redfish/v1/Systems/system/Storage/1"}}};
+                asyncResp->res.jsonValue["Members@odata.count"] = 1;
+            });
+}
 
-  private:
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&, const std::vector<std::string>&) override
-    {
-        asyncResp->res.jsonValue["@odata.type"] =
-            "#StorageCollection.StorageCollection";
-        asyncResp->res.jsonValue["@odata.id"] =
-            "/redfish/v1/Systems/system/Storage";
-        asyncResp->res.jsonValue["Name"] = "Storage Collection";
-        asyncResp->res.jsonValue["Members"] = {
-            {{"@odata.id", "/redfish/v1/Systems/system/Storage/1"}}};
-        asyncResp->res.jsonValue["Members@odata.count"] = 1;
-    }
-};
-
-class Storage : public Node
+inline void requestRoutesStorage(App& app)
 {
-  public:
-    Storage(App& app) : Node(app, "/redfish/v1/Systems/system/Storage/1/")
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
-    }
+    BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/Storage/1/")
+        .privileges({"Login"})
+        .methods(
+            boost::beast::http::verb::
+                get)([](const crow::Request&,
+                        const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+            asyncResp->res.jsonValue["@odata.type"] = "#Storage.v1_7_1.Storage";
+            asyncResp->res.jsonValue["@odata.id"] =
+                "/redfish/v1/Systems/system/Storage/1";
+            asyncResp->res.jsonValue["Name"] = "Storage";
+            asyncResp->res.jsonValue["Id"] = "1";
+            asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
 
-  private:
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&, const std::vector<std::string>&) override
-    {
-        asyncResp->res.jsonValue["@odata.type"] = "#Storage.v1_7_1.Storage";
-        asyncResp->res.jsonValue["@odata.id"] =
-            "/redfish/v1/Systems/system/Storage/1";
-        asyncResp->res.jsonValue["Name"] = "Storage";
-        asyncResp->res.jsonValue["Id"] = "1";
-        asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
+            auto health = std::make_shared<HealthPopulate>(asyncResp);
+            health->populate();
 
-        auto health = std::make_shared<HealthPopulate>(asyncResp);
-        health->populate();
+            crow::connections::systemBus->async_method_call(
+                [asyncResp,
+                 health](const boost::system::error_code ec,
+                         const std::vector<std::string>& storageList) {
+                    nlohmann::json& storageArray =
+                        asyncResp->res.jsonValue["Drives"];
+                    storageArray = nlohmann::json::array();
+                    auto& count =
+                        asyncResp->res.jsonValue["Drives@odata.count"];
+                    count = 0;
 
-        crow::connections::systemBus->async_method_call(
-            [asyncResp, health](const boost::system::error_code ec,
-                                const std::vector<std::string>& storageList) {
-                nlohmann::json& storageArray =
-                    asyncResp->res.jsonValue["Drives"];
-                storageArray = nlohmann::json::array();
-                auto& count = asyncResp->res.jsonValue["Drives@odata.count"];
-                count = 0;
-
-                if (ec)
-                {
-                    BMCWEB_LOG_ERROR << "Drive mapper call error";
-                    messages::internalError(asyncResp->res);
-                    return;
-                }
-
-                health->inventory.insert(health->inventory.end(),
-                                         storageList.begin(),
-                                         storageList.end());
-
-                for (const std::string& objpath : storageList)
-                {
-                    std::size_t lastPos = objpath.rfind('/');
-                    if (lastPos == std::string::npos ||
-                        (objpath.size() <= lastPos + 1))
+                    if (ec)
                     {
-                        BMCWEB_LOG_ERROR << "Failed to find '/' in " << objpath;
-                        continue;
-                    }
-
-                    storageArray.push_back(
-                        {{"@odata.id",
-                          "/redfish/v1/Systems/system/Storage/1/Drives/" +
-                              objpath.substr(lastPos + 1)}});
-                }
-
-                count = storageArray.size();
-            },
-            "xyz.openbmc_project.ObjectMapper",
-            "/xyz/openbmc_project/object_mapper",
-            "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths",
-            "/xyz/openbmc_project/inventory", int32_t(0),
-            std::array<const char*, 1>{
-                "xyz.openbmc_project.Inventory.Item.Drive"});
-
-        crow::connections::systemBus->async_method_call(
-            [asyncResp,
-             health](const boost::system::error_code ec,
-                     const crow::openbmc_mapper::GetSubTreeType& subtree) {
-                if (ec || !subtree.size())
-                {
-                    // doesn't have to be there
-                    return;
-                }
-
-                nlohmann::json& root =
-                    asyncResp->res.jsonValue["StorageControllers"];
-                root = nlohmann::json::array();
-                for (const auto& [path, interfaceDict] : subtree)
-                {
-                    std::size_t lastPos = path.rfind('/');
-                    if (lastPos == std::string::npos ||
-                        (path.size() <= lastPos + 1))
-                    {
-                        BMCWEB_LOG_ERROR << "Failed to find '/' in " << path;
+                        BMCWEB_LOG_ERROR << "Drive mapper call error";
+                        messages::internalError(asyncResp->res);
                         return;
                     }
 
-                    if (interfaceDict.size() != 1)
+                    health->inventory.insert(health->inventory.end(),
+                                             storageList.begin(),
+                                             storageList.end());
+
+                    for (const std::string& objpath : storageList)
+                    {
+                        std::size_t lastPos = objpath.rfind('/');
+                        if (lastPos == std::string::npos ||
+                            (objpath.size() <= lastPos + 1))
+                        {
+                            BMCWEB_LOG_ERROR << "Failed to find '/' in "
+                                             << objpath;
+                            continue;
+                        }
+
+                        storageArray.push_back(
+                            {{"@odata.id",
+                              "/redfish/v1/Systems/system/Storage/1/Drives/" +
+                                  objpath.substr(lastPos + 1)}});
+                    }
+
+                    count = storageArray.size();
+                },
+                "xyz.openbmc_project.ObjectMapper",
+                "/xyz/openbmc_project/object_mapper",
+                "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths",
+                "/xyz/openbmc_project/inventory", int32_t(0),
+                std::array<const char*, 1>{
+                    "xyz.openbmc_project.Inventory.Item.Drive"});
+
+            crow::connections::systemBus->async_method_call(
+                [asyncResp,
+                 health](const boost::system::error_code ec,
+                         const crow::openbmc_mapper::GetSubTreeType& subtree) {
+                    if (ec || !subtree.size())
+                    {
+                        // doesn't have to be there
+                        return;
+                    }
+
+                    nlohmann::json& root =
+                        asyncResp->res.jsonValue["StorageControllers"];
+                    root = nlohmann::json::array();
+                    for (const auto& [path, interfaceDict] : subtree)
+                    {
+                        std::size_t lastPos = path.rfind('/');
+                        if (lastPos == std::string::npos ||
+                            (path.size() <= lastPos + 1))
+                        {
+                            BMCWEB_LOG_ERROR << "Failed to find '/' in "
+                                             << path;
+                            return;
+                        }
+
+                        if (interfaceDict.size() != 1)
+                        {
+                            BMCWEB_LOG_ERROR << "Connection size "
+                                             << interfaceDict.size()
+                                             << ", greater than 1";
+                            messages::internalError(asyncResp->res);
+                            return;
+                        }
+
+                        const std::string& connectionName =
+                            interfaceDict.front().first;
+
+                        size_t index = root.size();
+                        nlohmann::json& storageController =
+                            root.emplace_back(nlohmann::json::object());
+
+                        std::string id = path.substr(lastPos + 1);
+
+                        storageController["@odata.type"] =
+                            "#Storage.v1_7_0.StorageController";
+                        storageController["@odata.id"] =
+                            "/redfish/v1/Systems/system/Storage/1"
+                            "#/StorageControllers/" +
+                            std::to_string(index);
+                        storageController["Name"] = id;
+                        storageController["MemberId"] = id;
+                        storageController["Status"]["State"] = "Enabled";
+
+                        crow::connections::systemBus->async_method_call(
+                            [asyncResp,
+                             index](const boost::system::error_code ec2,
+                                    const std::variant<bool> present) {
+                                // this interface isn't necessary, only check it
+                                // if we get a good return
+                                if (ec2)
+                                {
+                                    return;
+                                }
+                                const bool* enabled =
+                                    std::get_if<bool>(&present);
+                                if (enabled == nullptr)
+                                {
+                                    BMCWEB_LOG_DEBUG
+                                        << "Illegal property present";
+                                    messages::internalError(asyncResp->res);
+                                    return;
+                                }
+                                if (!(*enabled))
+                                {
+                                    asyncResp->res
+                                        .jsonValue["StorageControllers"][index]
+                                                  ["Status"]["State"] =
+                                        "Disabled";
+                                }
+                            },
+                            connectionName, path,
+                            "org.freedesktop.DBus.Properties", "Get",
+                            "xyz.openbmc_project.Inventory.Item", "Present");
+
+                        crow::connections::systemBus->async_method_call(
+                            [asyncResp, index](
+                                const boost::system::error_code ec2,
+                                const std::vector<std::pair<
+                                    std::string,
+                                    std::variant<bool, std::string, uint64_t>>>&
+                                    propertiesList) {
+                                if (ec2)
+                                {
+                                    // this interface isn't necessary
+                                    return;
+                                }
+                                for (const std::pair<
+                                         std::string,
+                                         std::variant<bool, std::string,
+                                                      uint64_t>>& property :
+                                     propertiesList)
+                                {
+                                    // Store DBus properties that are also
+                                    // Redfish properties with same name and a
+                                    // string value
+                                    const std::string& propertyName =
+                                        property.first;
+                                    nlohmann::json& object =
+                                        asyncResp->res
+                                            .jsonValue["StorageControllers"]
+                                                      [index];
+                                    if ((propertyName == "PartNumber") ||
+                                        (propertyName == "SerialNumber") ||
+                                        (propertyName == "Manufacturer") ||
+                                        (propertyName == "Model"))
+                                    {
+                                        const std::string* value =
+                                            std::get_if<std::string>(
+                                                &property.second);
+                                        if (value == nullptr)
+                                        {
+                                            // illegal property
+                                            messages::internalError(
+                                                asyncResp->res);
+                                            return;
+                                        }
+                                        object[propertyName] = *value;
+                                    }
+                                }
+                            },
+                            connectionName, path,
+                            "org.freedesktop.DBus.Properties", "GetAll",
+                            "xyz.openbmc_project.Inventory.Decorator.Asset");
+                    }
+
+                    // this is done after we know the json array will no longer
+                    // be resized, as json::array uses vector underneath and we
+                    // need references to its members that won't change
+                    size_t count = 0;
+                    for (const auto& [path, interfaceDict] : subtree)
+                    {
+                        auto subHealth = std::make_shared<HealthPopulate>(
+                            asyncResp, root[count]["Status"]);
+                        subHealth->inventory.emplace_back(path);
+                        health->inventory.emplace_back(path);
+                        health->children.emplace_back(subHealth);
+                        count++;
+                    }
+                },
+                "xyz.openbmc_project.ObjectMapper",
+                "/xyz/openbmc_project/object_mapper",
+                "xyz.openbmc_project.ObjectMapper", "GetSubTree",
+                "/xyz/openbmc_project/inventory", int32_t(0),
+                std::array<const char*, 1>{
+                    "xyz.openbmc_project.Inventory.Item.StorageController"});
+        });
+}
+
+inline void requestRoutesDrive(App& app)
+{
+    BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/Storage/1/Drives/<str>/")
+        .privileges({"Login"})
+        .methods(
+            boost::beast::http::verb::get)([](const crow::Request&,
+                                              const std::shared_ptr<
+                                                  bmcweb::AsyncResp>& asyncResp,
+                                              const std::string& driveId) {
+            crow::connections::systemBus->async_method_call(
+                [asyncResp,
+                 driveId](const boost::system::error_code ec,
+                          const crow::openbmc_mapper::GetSubTreeType& subtree) {
+                    if (ec)
+                    {
+                        BMCWEB_LOG_ERROR << "Drive mapper call error";
+                        messages::internalError(asyncResp->res);
+                        return;
+                    }
+
+                    auto object2 = std::find_if(
+                        subtree.begin(), subtree.end(),
+                        [&driveId](auto& object) {
+                            const std::string& path = object.first;
+                            return boost::ends_with(path, "/" + driveId);
+                        });
+
+                    if (object2 == subtree.end())
+                    {
+                        messages::resourceNotFound(asyncResp->res, "Drive",
+                                                   driveId);
+                        return;
+                    }
+
+                    const std::string& path = object2->first;
+                    const std::vector<
+                        std::pair<std::string, std::vector<std::string>>>&
+                        connectionNames = object2->second;
+
+                    asyncResp->res.jsonValue["@odata.type"] =
+                        "#Drive.v1_7_0.Drive";
+                    asyncResp->res.jsonValue["@odata.id"] =
+                        "/redfish/v1/Systems/system/Storage/1/Drives/" +
+                        driveId;
+                    asyncResp->res.jsonValue["Name"] = driveId;
+                    asyncResp->res.jsonValue["Id"] = driveId;
+
+                    if (connectionNames.size() != 1)
                     {
                         BMCWEB_LOG_ERROR << "Connection size "
-                                         << interfaceDict.size()
+                                         << connectionNames.size()
                                          << ", greater than 1";
                         messages::internalError(asyncResp->res);
                         return;
                     }
 
+                    getMainChassisId(
+                        asyncResp,
+                        [](const std::string& chassisId,
+                           const std::shared_ptr<bmcweb::AsyncResp>& aRsp) {
+                            aRsp->res.jsonValue["Links"]["Chassis"] = {
+                                {"@odata.id",
+                                 "/redfish/v1/Chassis/" + chassisId}};
+                        });
+
                     const std::string& connectionName =
-                        interfaceDict.front().first;
-
-                    size_t index = root.size();
-                    nlohmann::json& storageController =
-                        root.emplace_back(nlohmann::json::object());
-
-                    std::string id = path.substr(lastPos + 1);
-
-                    storageController["@odata.type"] =
-                        "#Storage.v1_7_0.StorageController";
-                    storageController["@odata.id"] =
-                        "/redfish/v1/Systems/system/Storage/1"
-                        "#/StorageControllers/" +
-                        std::to_string(index);
-                    storageController["Name"] = id;
-                    storageController["MemberId"] = id;
-                    storageController["Status"]["State"] = "Enabled";
-
+                        connectionNames[0].first;
                     crow::connections::systemBus->async_method_call(
-                        [asyncResp, index](const boost::system::error_code ec2,
-                                           const std::variant<bool> present) {
-                            // this interface isn't necessary, only check it if
-                            // we get a good return
-                            if (ec2)
-                            {
-                                return;
-                            }
-                            const bool* enabled = std::get_if<bool>(&present);
-                            if (enabled == nullptr)
-                            {
-                                BMCWEB_LOG_DEBUG << "Illegal property present";
-                                messages::internalError(asyncResp->res);
-                                return;
-                            }
-                            if (!(*enabled))
-                            {
-                                asyncResp->res
-                                    .jsonValue["StorageControllers"][index]
-                                              ["Status"]["State"] = "Disabled";
-                            }
-                        },
-                        connectionName, path, "org.freedesktop.DBus.Properties",
-                        "Get", "xyz.openbmc_project.Inventory.Item", "Present");
-
-                    crow::connections::systemBus->async_method_call(
-                        [asyncResp,
-                         index](const boost::system::error_code ec2,
-                                const std::vector<std::pair<
-                                    std::string,
-                                    std::variant<bool, std::string, uint64_t>>>&
-                                    propertiesList) {
+                        [asyncResp](
+                            const boost::system::error_code ec2,
+                            const std::vector<std::pair<
+                                std::string,
+                                std::variant<bool, std::string, uint64_t>>>&
+                                propertiesList) {
                             if (ec2)
                             {
                                 // this interface isn't necessary
@@ -224,9 +352,6 @@
                                 // string value
                                 const std::string& propertyName =
                                     property.first;
-                                nlohmann::json& object =
-                                    asyncResp->res
-                                        .jsonValue["StorageControllers"][index];
                                 if ((propertyName == "PartNumber") ||
                                     (propertyName == "SerialNumber") ||
                                     (propertyName == "Manufacturer") ||
@@ -241,226 +366,84 @@
                                         messages::internalError(asyncResp->res);
                                         return;
                                     }
-                                    object[propertyName] = *value;
+                                    asyncResp->res.jsonValue[propertyName] =
+                                        *value;
                                 }
                             }
                         },
                         connectionName, path, "org.freedesktop.DBus.Properties",
                         "GetAll",
                         "xyz.openbmc_project.Inventory.Decorator.Asset");
-                }
 
-                // this is done after we know the json array will no longer be
-                // resized, as json::array uses vector underneath and we need
-                // references to its members that won't change
-                size_t count = 0;
-                for (const auto& [path, interfaceDict] : subtree)
-                {
-                    auto subHealth = std::make_shared<HealthPopulate>(
-                        asyncResp, root[count]["Status"]);
-                    subHealth->inventory.emplace_back(path);
+                    // default it to Enabled
+                    asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
+
+                    auto health = std::make_shared<HealthPopulate>(asyncResp);
                     health->inventory.emplace_back(path);
-                    health->children.emplace_back(subHealth);
-                    count++;
-                }
-            },
-            "xyz.openbmc_project.ObjectMapper",
-            "/xyz/openbmc_project/object_mapper",
-            "xyz.openbmc_project.ObjectMapper", "GetSubTree",
-            "/xyz/openbmc_project/inventory", int32_t(0),
-            std::array<const char*, 1>{
-                "xyz.openbmc_project.Inventory.Item.StorageController"});
-    }
-};
+                    health->populate();
 
-class Drive : public Node
-{
-  public:
-    Drive(App& app) :
-        Node(app, "/redfish/v1/Systems/system/Storage/1/Drives/<str>/",
-             std::string())
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
-    }
-
-  private:
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&,
-               const std::vector<std::string>& params) override
-    {
-        if (params.size() != 1)
-        {
-            messages::internalError(asyncResp->res);
-            return;
-        }
-        const std::string& driveId = params[0];
-
-        crow::connections::systemBus->async_method_call(
-            [asyncResp,
-             driveId](const boost::system::error_code ec,
-                      const crow::openbmc_mapper::GetSubTreeType& subtree) {
-                if (ec)
-                {
-                    BMCWEB_LOG_ERROR << "Drive mapper call error";
-                    messages::internalError(asyncResp->res);
-                    return;
-                }
-
-                auto object2 = std::find_if(
-                    subtree.begin(), subtree.end(), [&driveId](auto& object) {
-                        const std::string& path = object.first;
-                        return boost::ends_with(path, "/" + driveId);
-                    });
-
-                if (object2 == subtree.end())
-                {
-                    messages::resourceNotFound(asyncResp->res, "Drive",
-                                               driveId);
-                    return;
-                }
-
-                const std::string& path = object2->first;
-                const std::vector<
-                    std::pair<std::string, std::vector<std::string>>>&
-                    connectionNames = object2->second;
-
-                asyncResp->res.jsonValue["@odata.type"] = "#Drive.v1_7_0.Drive";
-                asyncResp->res.jsonValue["@odata.id"] =
-                    "/redfish/v1/Systems/system/Storage/1/Drives/" + driveId;
-                asyncResp->res.jsonValue["Name"] = driveId;
-                asyncResp->res.jsonValue["Id"] = driveId;
-
-                if (connectionNames.size() != 1)
-                {
-                    BMCWEB_LOG_ERROR << "Connection size "
-                                     << connectionNames.size()
-                                     << ", greater than 1";
-                    messages::internalError(asyncResp->res);
-                    return;
-                }
-
-                getMainChassisId(
-                    asyncResp,
-                    [](const std::string& chassisId,
-                       const std::shared_ptr<bmcweb::AsyncResp>& aRsp) {
-                        aRsp->res.jsonValue["Links"]["Chassis"] = {
-                            {"@odata.id", "/redfish/v1/Chassis/" + chassisId}};
-                    });
-
-                const std::string& connectionName = connectionNames[0].first;
-                crow::connections::systemBus->async_method_call(
-                    [asyncResp](const boost::system::error_code ec2,
-                                const std::vector<std::pair<
-                                    std::string,
-                                    std::variant<bool, std::string, uint64_t>>>&
-                                    propertiesList) {
-                        if (ec2)
-                        {
-                            // this interface isn't necessary
-                            return;
-                        }
-                        for (const std::pair<std::string,
-                                             std::variant<bool, std::string,
-                                                          uint64_t>>& property :
-                             propertiesList)
-                        {
-                            // Store DBus properties that are also
-                            // Redfish properties with same name and a
-                            // string value
-                            const std::string& propertyName = property.first;
-                            if ((propertyName == "PartNumber") ||
-                                (propertyName == "SerialNumber") ||
-                                (propertyName == "Manufacturer") ||
-                                (propertyName == "Model"))
+                    crow::connections::systemBus->async_method_call(
+                        [asyncResp, path](const boost::system::error_code ec2,
+                                          const std::variant<bool> present) {
+                            // this interface isn't necessary, only check it if
+                            // we get a good return
+                            if (ec2)
                             {
-                                const std::string* value =
-                                    std::get_if<std::string>(&property.second);
-                                if (value == nullptr)
-                                {
-                                    // illegal property
-                                    messages::internalError(asyncResp->res);
-                                    return;
-                                }
-                                asyncResp->res.jsonValue[propertyName] = *value;
+                                return;
                             }
-                        }
-                    },
-                    connectionName, path, "org.freedesktop.DBus.Properties",
-                    "GetAll", "xyz.openbmc_project.Inventory.Decorator.Asset");
+                            const bool* enabled = std::get_if<bool>(&present);
+                            if (enabled == nullptr)
+                            {
+                                BMCWEB_LOG_DEBUG << "Illegal property present";
+                                messages::internalError(asyncResp->res);
+                                return;
+                            }
+                            if (!(*enabled))
+                            {
+                                asyncResp->res.jsonValue["Status"]["State"] =
+                                    "Disabled";
+                            }
+                        },
+                        connectionName, path, "org.freedesktop.DBus.Properties",
+                        "Get", "xyz.openbmc_project.Inventory.Item", "Present");
 
-                // default it to Enabled
-                asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
+                    crow::connections::systemBus->async_method_call(
+                        [asyncResp](const boost::system::error_code ec2,
+                                    const std::variant<bool> rebuilding) {
+                            // this interface isn't necessary, only check it if
+                            // we get a good return
+                            if (ec2)
+                            {
+                                return;
+                            }
+                            const bool* updating =
+                                std::get_if<bool>(&rebuilding);
+                            if (updating == nullptr)
+                            {
+                                BMCWEB_LOG_DEBUG << "Illegal property present";
+                                messages::internalError(asyncResp->res);
+                                return;
+                            }
 
-                auto health = std::make_shared<HealthPopulate>(asyncResp);
-                health->inventory.emplace_back(path);
-                health->populate();
-
-                crow::connections::systemBus->async_method_call(
-                    [asyncResp, path](const boost::system::error_code ec2,
-                                      const std::variant<bool> present) {
-                        // this interface isn't necessary, only check it if we
-                        // get a good return
-                        if (ec2)
-                        {
-                            return;
-                        }
-                        const bool* enabled = std::get_if<bool>(&present);
-                        if (enabled == nullptr)
-                        {
-                            BMCWEB_LOG_DEBUG << "Illegal property present";
-                            messages::internalError(asyncResp->res);
-                            return;
-                        }
-                        if (!(*enabled))
-                        {
-                            asyncResp->res.jsonValue["Status"]["State"] =
-                                "Disabled";
-                        }
-                    },
-                    connectionName, path, "org.freedesktop.DBus.Properties",
-                    "Get", "xyz.openbmc_project.Inventory.Item", "Present");
-
-                crow::connections::systemBus->async_method_call(
-                    [asyncResp](const boost::system::error_code ec2,
-                                const std::variant<bool> rebuilding) {
-                        // this interface isn't necessary, only check it if we
-                        // get a good return
-                        if (ec2)
-                        {
-                            return;
-                        }
-                        const bool* updating = std::get_if<bool>(&rebuilding);
-                        if (updating == nullptr)
-                        {
-                            BMCWEB_LOG_DEBUG << "Illegal property present";
-                            messages::internalError(asyncResp->res);
-                            return;
-                        }
-
-                        // updating and disabled in the backend shouldn't be
-                        // able to be set at the same time, so we don't need to
-                        // check for the race condition of these two calls
-                        if ((*updating))
-                        {
-                            asyncResp->res.jsonValue["Status"]["State"] =
-                                "Updating";
-                        }
-                    },
-                    connectionName, path, "org.freedesktop.DBus.Properties",
-                    "Get", "xyz.openbmc_project.State.Drive", "Rebuilding");
-            },
-            "xyz.openbmc_project.ObjectMapper",
-            "/xyz/openbmc_project/object_mapper",
-            "xyz.openbmc_project.ObjectMapper", "GetSubTree",
-            "/xyz/openbmc_project/inventory", int32_t(0),
-            std::array<const char*, 1>{
-                "xyz.openbmc_project.Inventory.Item.Drive"});
-    }
-};
+                            // updating and disabled in the backend shouldn't be
+                            // able to be set at the same time, so we don't need
+                            // to check for the race condition of these two
+                            // calls
+                            if ((*updating))
+                            {
+                                asyncResp->res.jsonValue["Status"]["State"] =
+                                    "Updating";
+                            }
+                        },
+                        connectionName, path, "org.freedesktop.DBus.Properties",
+                        "Get", "xyz.openbmc_project.State.Drive", "Rebuilding");
+                },
+                "xyz.openbmc_project.ObjectMapper",
+                "/xyz/openbmc_project/object_mapper",
+                "xyz.openbmc_project.ObjectMapper", "GetSubTree",
+                "/xyz/openbmc_project/inventory", int32_t(0),
+                std::array<const char*, 1>{
+                    "xyz.openbmc_project.Inventory.Item.Drive"});
+        });
+}
 } // namespace redfish
diff --git a/redfish-core/lib/systems.hpp b/redfish-core/lib/systems.hpp
index 13cbcf3..2656a20 100644
--- a/redfish-core/lib/systems.hpp
+++ b/redfish-core/lib/systems.hpp
@@ -20,8 +20,8 @@
 #include "pcie.hpp"
 #include "redfish_util.hpp"
 
+#include <app.hpp>
 #include <boost/container/flat_map.hpp>
-#include <node.hpp>
 #include <utils/fw_utils.hpp>
 #include <utils/json_utils.hpp>
 
@@ -1858,456 +1858,426 @@
  * SystemsCollection derived class for delivering ComputerSystems Collection
  * Schema
  */
-class SystemsCollection : public Node
+inline void requestRoutesSystemsCollection(App& app)
 {
-  public:
-    SystemsCollection(App& app) : Node(app, "/redfish/v1/Systems/")
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
-    }
+    BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
+        .privileges({"Login"})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request& req,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                asyncResp->res.jsonValue["@odata.type"] =
+                    "#ComputerSystemCollection.ComputerSystemCollection";
+                asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
+                asyncResp->res.jsonValue["Name"] = "Computer System Collection";
 
-  private:
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request& req,
-               const std::vector<std::string>&) override
-    {
-        asyncResp->res.jsonValue["@odata.type"] =
-            "#ComputerSystemCollection.ComputerSystemCollection";
-        asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
-        asyncResp->res.jsonValue["Name"] = "Computer System Collection";
+                crow::connections::systemBus->async_method_call(
+                    [asyncResp,
+                     &req](const boost::system::error_code ec,
+                           const std::variant<std::string>& /*hostName*/) {
+                        nlohmann::json& ifaceArray =
+                            asyncResp->res.jsonValue["Members"];
+                        ifaceArray = nlohmann::json::array();
+                        auto& count =
+                            asyncResp->res.jsonValue["Members@odata.count"];
+                        ifaceArray.push_back(
+                            {{"@odata.id", "/redfish/v1/Systems/system"}});
+                        count = ifaceArray.size();
+                        if (!ec)
+                        {
+                            BMCWEB_LOG_DEBUG << "Hypervisor is available";
+                            ifaceArray.push_back(
+                                {{"@odata.id",
+                                  "/redfish/v1/Systems/hypervisor"}});
+                            count = ifaceArray.size();
+                        }
+                    },
+                    "xyz.openbmc_project.Settings",
+                    "/xyz/openbmc_project/network/hypervisor",
+                    "org.freedesktop.DBus.Properties", "Get",
+                    "xyz.openbmc_project.Network.SystemConfiguration",
+                    "HostName");
+            });
+}
 
-        crow::connections::systemBus->async_method_call(
-            [asyncResp, &req](const boost::system::error_code ec,
-                              const std::variant<std::string>& /*hostName*/) {
-                nlohmann::json& ifaceArray =
-                    asyncResp->res.jsonValue["Members"];
-                ifaceArray = nlohmann::json::array();
-                auto& count = asyncResp->res.jsonValue["Members@odata.count"];
-                ifaceArray.push_back(
-                    {{"@odata.id", "/redfish/v1/Systems/system"}});
-                count = ifaceArray.size();
-                if (!ec)
-                {
-                    BMCWEB_LOG_DEBUG << "Hypervisor is available";
-                    ifaceArray.push_back(
-                        {{"@odata.id", "/redfish/v1/Systems/hypervisor"}});
-                    count = ifaceArray.size();
-                }
-            },
-            "xyz.openbmc_project.Settings",
-            "/xyz/openbmc_project/network/hypervisor",
-            "org.freedesktop.DBus.Properties", "Get",
-            "xyz.openbmc_project.Network.SystemConfiguration", "HostName");
-    }
-};
+/**
+ * Function transceives data with dbus directly.
+ */
+void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+{
+    constexpr char const* serviceName = "xyz.openbmc_project.Control.Host.NMI";
+    constexpr char const* objectPath = "/xyz/openbmc_project/control/host0/nmi";
+    constexpr char const* interfaceName =
+        "xyz.openbmc_project.Control.Host.NMI";
+    constexpr char const* method = "NMI";
+
+    crow::connections::systemBus->async_method_call(
+        [asyncResp](const boost::system::error_code ec) {
+            if (ec)
+            {
+                BMCWEB_LOG_ERROR << " Bad D-Bus request error: " << ec;
+                messages::internalError(asyncResp->res);
+                return;
+            }
+            messages::success(asyncResp->res);
+        },
+        serviceName, objectPath, interfaceName, method);
+}
 
 /**
  * SystemActionsReset class supports handle POST method for Reset action.
  * The class retrieves and sends data directly to D-Bus.
  */
-class SystemActionsReset : public Node
+inline void requestRoutesSystemActionsReset(App& app)
 {
-  public:
-    SystemActionsReset(App& app) :
-        Node(app, "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset/")
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
-    }
-
-  private:
     /**
      * Function handles POST method request.
      * Analyzes POST body message before sends Reset request data to D-Bus.
      */
-    void doPost(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                const crow::Request& req,
-                const std::vector<std::string>&) override
-    {
+    BMCWEB_ROUTE(app,
+                 "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset/")
+        .privileges({"ConfigureComponent"})
+        .methods(
+            boost::beast::http::verb::
+                post)([](const crow::Request& req,
+                         const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+            std::string resetType;
+            if (!json_util::readJson(req, asyncResp->res, "ResetType",
+                                     resetType))
+            {
+                return;
+            }
 
-        std::string resetType;
-        if (!json_util::readJson(req, asyncResp->res, "ResetType", resetType))
-        {
-            return;
-        }
+            // Get the command and host vs. chassis
+            std::string command;
+            bool hostCommand;
+            if ((resetType == "On") || (resetType == "ForceOn"))
+            {
+                command = "xyz.openbmc_project.State.Host.Transition.On";
+                hostCommand = true;
+            }
+            else if (resetType == "ForceOff")
+            {
+                command = "xyz.openbmc_project.State.Chassis.Transition.Off";
+                hostCommand = false;
+            }
+            else if (resetType == "ForceRestart")
+            {
+                command =
+                    "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot";
+                hostCommand = true;
+            }
+            else if (resetType == "GracefulShutdown")
+            {
+                command = "xyz.openbmc_project.State.Host.Transition.Off";
+                hostCommand = true;
+            }
+            else if (resetType == "GracefulRestart")
+            {
+                command = "xyz.openbmc_project.State.Host.Transition."
+                          "GracefulWarmReboot";
+                hostCommand = true;
+            }
+            else if (resetType == "PowerCycle")
+            {
+                command = "xyz.openbmc_project.State.Host.Transition.Reboot";
+                hostCommand = true;
+            }
+            else if (resetType == "Nmi")
+            {
+                doNMI(asyncResp);
+                return;
+            }
+            else
+            {
+                messages::actionParameterUnknown(asyncResp->res, "Reset",
+                                                 resetType);
+                return;
+            }
 
-        // Get the command and host vs. chassis
-        std::string command;
-        bool hostCommand;
-        if ((resetType == "On") || (resetType == "ForceOn"))
-        {
-            command = "xyz.openbmc_project.State.Host.Transition.On";
-            hostCommand = true;
-        }
-        else if (resetType == "ForceOff")
-        {
-            command = "xyz.openbmc_project.State.Chassis.Transition.Off";
-            hostCommand = false;
-        }
-        else if (resetType == "ForceRestart")
-        {
-            command =
-                "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot";
-            hostCommand = true;
-        }
-        else if (resetType == "GracefulShutdown")
-        {
-            command = "xyz.openbmc_project.State.Host.Transition.Off";
-            hostCommand = true;
-        }
-        else if (resetType == "GracefulRestart")
-        {
-            command =
-                "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot";
-            hostCommand = true;
-        }
-        else if (resetType == "PowerCycle")
-        {
-            command = "xyz.openbmc_project.State.Host.Transition.Reboot";
-            hostCommand = true;
-        }
-        else if (resetType == "Nmi")
-        {
-            doNMI(asyncResp);
-            return;
-        }
-        else
-        {
-            messages::actionParameterUnknown(asyncResp->res, "Reset",
-                                             resetType);
-            return;
-        }
-
-        if (hostCommand)
-        {
-            crow::connections::systemBus->async_method_call(
-                [asyncResp, resetType](const boost::system::error_code ec) {
-                    if (ec)
-                    {
-                        BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
-                        if (ec.value() == boost::asio::error::invalid_argument)
+            if (hostCommand)
+            {
+                crow::connections::systemBus->async_method_call(
+                    [asyncResp, resetType](const boost::system::error_code ec) {
+                        if (ec)
                         {
-                            messages::actionParameterNotSupported(
-                                asyncResp->res, resetType, "Reset");
+                            BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
+                            if (ec.value() ==
+                                boost::asio::error::invalid_argument)
+                            {
+                                messages::actionParameterNotSupported(
+                                    asyncResp->res, resetType, "Reset");
+                            }
+                            else
+                            {
+                                messages::internalError(asyncResp->res);
+                            }
+                            return;
                         }
-                        else
+                        messages::success(asyncResp->res);
+                    },
+                    "xyz.openbmc_project.State.Host",
+                    "/xyz/openbmc_project/state/host0",
+                    "org.freedesktop.DBus.Properties", "Set",
+                    "xyz.openbmc_project.State.Host", "RequestedHostTransition",
+                    std::variant<std::string>{command});
+            }
+            else
+            {
+                crow::connections::systemBus->async_method_call(
+                    [asyncResp, resetType](const boost::system::error_code ec) {
+                        if (ec)
                         {
-                            messages::internalError(asyncResp->res);
+                            BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
+                            if (ec.value() ==
+                                boost::asio::error::invalid_argument)
+                            {
+                                messages::actionParameterNotSupported(
+                                    asyncResp->res, resetType, "Reset");
+                            }
+                            else
+                            {
+                                messages::internalError(asyncResp->res);
+                            }
+                            return;
                         }
-                        return;
-                    }
-                    messages::success(asyncResp->res);
-                },
-                "xyz.openbmc_project.State.Host",
-                "/xyz/openbmc_project/state/host0",
-                "org.freedesktop.DBus.Properties", "Set",
-                "xyz.openbmc_project.State.Host", "RequestedHostTransition",
-                std::variant<std::string>{command});
-        }
-        else
-        {
-            crow::connections::systemBus->async_method_call(
-                [asyncResp, resetType](const boost::system::error_code ec) {
-                    if (ec)
-                    {
-                        BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
-                        if (ec.value() == boost::asio::error::invalid_argument)
-                        {
-                            messages::actionParameterNotSupported(
-                                asyncResp->res, resetType, "Reset");
-                        }
-                        else
-                        {
-                            messages::internalError(asyncResp->res);
-                        }
-                        return;
-                    }
-                    messages::success(asyncResp->res);
-                },
-                "xyz.openbmc_project.State.Chassis",
-                "/xyz/openbmc_project/state/chassis0",
-                "org.freedesktop.DBus.Properties", "Set",
-                "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition",
-                std::variant<std::string>{command});
-        }
-    }
-    /**
-     * Function transceives data with dbus directly.
-     */
-    void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
-    {
-        constexpr char const* serviceName =
-            "xyz.openbmc_project.Control.Host.NMI";
-        constexpr char const* objectPath =
-            "/xyz/openbmc_project/control/host0/nmi";
-        constexpr char const* interfaceName =
-            "xyz.openbmc_project.Control.Host.NMI";
-        constexpr char const* method = "NMI";
-
-        crow::connections::systemBus->async_method_call(
-            [asyncResp](const boost::system::error_code ec) {
-                if (ec)
-                {
-                    BMCWEB_LOG_ERROR << " Bad D-Bus request error: " << ec;
-                    messages::internalError(asyncResp->res);
-                    return;
-                }
-                messages::success(asyncResp->res);
-            },
-            serviceName, objectPath, interfaceName, method);
-    }
-};
+                        messages::success(asyncResp->res);
+                    },
+                    "xyz.openbmc_project.State.Chassis",
+                    "/xyz/openbmc_project/state/chassis0",
+                    "org.freedesktop.DBus.Properties", "Set",
+                    "xyz.openbmc_project.State.Chassis",
+                    "RequestedPowerTransition",
+                    std::variant<std::string>{command});
+            }
+        });
+}
 
 /**
  * Systems derived class for delivering Computer Systems Schema.
  */
-class Systems : public Node
+inline void requestRoutesSystems(App& app)
 {
-  public:
-    /*
-     * Default Constructor
-     */
-    Systems(App& app) : Node(app, "/redfish/v1/Systems/system/")
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
-    }
 
-  private:
     /**
      * Functions triggers appropriate requests on DBus
      */
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&, const std::vector<std::string>&) override
-    {
-        asyncResp->res.jsonValue["@odata.type"] =
-            "#ComputerSystem.v1_13_0.ComputerSystem";
-        asyncResp->res.jsonValue["Name"] = "system";
-        asyncResp->res.jsonValue["Id"] = "system";
-        asyncResp->res.jsonValue["SystemType"] = "Physical";
-        asyncResp->res.jsonValue["Description"] = "Computer System";
-        asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0;
-        asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
-            "Disabled";
-        asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
-            uint64_t(0);
-        asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
-            "Disabled";
-        asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system";
+    BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/")
+        .privileges({"Login"})
+        .methods(
+            boost::beast::http::verb::
+                get)([](const crow::Request&,
+                        const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+            asyncResp->res.jsonValue["@odata.type"] =
+                "#ComputerSystem.v1_13_0.ComputerSystem";
+            asyncResp->res.jsonValue["Name"] = "system";
+            asyncResp->res.jsonValue["Id"] = "system";
+            asyncResp->res.jsonValue["SystemType"] = "Physical";
+            asyncResp->res.jsonValue["Description"] = "Computer System";
+            asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0;
+            asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
+                "Disabled";
+            asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
+                uint64_t(0);
+            asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
+                "Disabled";
+            asyncResp->res.jsonValue["@odata.id"] =
+                "/redfish/v1/Systems/system";
 
-        asyncResp->res.jsonValue["Processors"] = {
-            {"@odata.id", "/redfish/v1/Systems/system/Processors"}};
-        asyncResp->res.jsonValue["Memory"] = {
-            {"@odata.id", "/redfish/v1/Systems/system/Memory"}};
-        asyncResp->res.jsonValue["Storage"] = {
-            {"@odata.id", "/redfish/v1/Systems/system/Storage"}};
+            asyncResp->res.jsonValue["Processors"] = {
+                {"@odata.id", "/redfish/v1/Systems/system/Processors"}};
+            asyncResp->res.jsonValue["Memory"] = {
+                {"@odata.id", "/redfish/v1/Systems/system/Memory"}};
+            asyncResp->res.jsonValue["Storage"] = {
+                {"@odata.id", "/redfish/v1/Systems/system/Storage"}};
 
-        asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"] = {
-            {"target",
-             "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset"},
-            {"@Redfish.ActionInfo",
-             "/redfish/v1/Systems/system/ResetActionInfo"}};
+            asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"] = {
+                {"target",
+                 "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset"},
+                {"@Redfish.ActionInfo",
+                 "/redfish/v1/Systems/system/ResetActionInfo"}};
 
-        asyncResp->res.jsonValue["LogServices"] = {
-            {"@odata.id", "/redfish/v1/Systems/system/LogServices"}};
+            asyncResp->res.jsonValue["LogServices"] = {
+                {"@odata.id", "/redfish/v1/Systems/system/LogServices"}};
 
-        asyncResp->res.jsonValue["Bios"] = {
-            {"@odata.id", "/redfish/v1/Systems/system/Bios"}};
+            asyncResp->res.jsonValue["Bios"] = {
+                {"@odata.id", "/redfish/v1/Systems/system/Bios"}};
 
-        asyncResp->res.jsonValue["Links"]["ManagedBy"] = {
-            {{"@odata.id", "/redfish/v1/Managers/bmc"}}};
+            asyncResp->res.jsonValue["Links"]["ManagedBy"] = {
+                {{"@odata.id", "/redfish/v1/Managers/bmc"}}};
 
-        asyncResp->res.jsonValue["Status"] = {
-            {"Health", "OK"},
-            {"State", "Enabled"},
-        };
-        constexpr const std::array<const char*, 4> inventoryForSystems = {
-            "xyz.openbmc_project.Inventory.Item.Dimm",
-            "xyz.openbmc_project.Inventory.Item.Cpu",
-            "xyz.openbmc_project.Inventory.Item.Drive",
-            "xyz.openbmc_project.Inventory.Item.StorageController"};
+            asyncResp->res.jsonValue["Status"] = {
+                {"Health", "OK"},
+                {"State", "Enabled"},
+            };
+            constexpr const std::array<const char*, 4> inventoryForSystems = {
+                "xyz.openbmc_project.Inventory.Item.Dimm",
+                "xyz.openbmc_project.Inventory.Item.Cpu",
+                "xyz.openbmc_project.Inventory.Item.Drive",
+                "xyz.openbmc_project.Inventory.Item.StorageController"};
 
-        auto health = std::make_shared<HealthPopulate>(asyncResp);
-        crow::connections::systemBus->async_method_call(
-            [health](const boost::system::error_code ec,
-                     std::vector<std::string>& resp) {
-                if (ec)
+            auto health = std::make_shared<HealthPopulate>(asyncResp);
+            crow::connections::systemBus->async_method_call(
+                [health](const boost::system::error_code ec,
+                         std::vector<std::string>& resp) {
+                    if (ec)
+                    {
+                        // no inventory
+                        return;
+                    }
+
+                    health->inventory = std::move(resp);
+                },
+                "xyz.openbmc_project.ObjectMapper",
+                "/xyz/openbmc_project/object_mapper",
+                "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", "/",
+                int32_t(0), inventoryForSystems);
+
+            health->populate();
+
+            getMainChassisId(
+                asyncResp, [](const std::string& chassisId,
+                              const std::shared_ptr<bmcweb::AsyncResp>& aRsp) {
+                    aRsp->res.jsonValue["Links"]["Chassis"] = {
+                        {{"@odata.id", "/redfish/v1/Chassis/" + chassisId}}};
+                });
+
+            getLocationIndicatorActive(asyncResp);
+            // TODO (Gunnar): Remove IndicatorLED after enough time has passed
+            getIndicatorLedState(asyncResp);
+            getComputerSystem(asyncResp, health);
+            getHostState(asyncResp);
+            getBootProperties(asyncResp);
+            getBootProgress(asyncResp);
+            getPCIeDeviceList(asyncResp, "PCIeDevices");
+            getHostWatchdogTimer(asyncResp);
+            getPowerRestorePolicy(asyncResp);
+            getAutomaticRetry(asyncResp);
+            getLastResetTime(asyncResp);
+#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
+            getProvisioningStatus(asyncResp);
+#endif
+        });
+    BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/")
+        .privileges({"ConfigureComponent"})
+        .methods(boost::beast::http::verb::patch)(
+            [](const crow::Request& req,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                std::optional<bool> locationIndicatorActive;
+                std::optional<std::string> indicatorLed;
+                std::optional<nlohmann::json> bootProps;
+                std::optional<nlohmann::json> wdtTimerProps;
+                std::optional<std::string> assetTag;
+                std::optional<std::string> powerRestorePolicy;
+
+                if (!json_util::readJson(
+                        req, asyncResp->res, "IndicatorLED", indicatorLed,
+                        "LocationIndicatorActive", locationIndicatorActive,
+                        "Boot", bootProps, "WatchdogTimer", wdtTimerProps,
+                        "PowerRestorePolicy", powerRestorePolicy, "AssetTag",
+                        assetTag))
                 {
-                    // no inventory
                     return;
                 }
 
-                health->inventory = std::move(resp);
-            },
-            "xyz.openbmc_project.ObjectMapper",
-            "/xyz/openbmc_project/object_mapper",
-            "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", "/",
-            int32_t(0), inventoryForSystems);
+                asyncResp->res.result(boost::beast::http::status::no_content);
 
-        health->populate();
+                if (assetTag)
+                {
+                    setAssetTag(asyncResp, *assetTag);
+                }
 
-        getMainChassisId(
-            asyncResp, [](const std::string& chassisId,
-                          const std::shared_ptr<bmcweb::AsyncResp>& aRsp) {
-                aRsp->res.jsonValue["Links"]["Chassis"] = {
-                    {{"@odata.id", "/redfish/v1/Chassis/" + chassisId}}};
+                if (wdtTimerProps)
+                {
+                    std::optional<bool> wdtEnable;
+                    std::optional<std::string> wdtTimeOutAction;
+
+                    if (!json_util::readJson(*wdtTimerProps, asyncResp->res,
+                                             "FunctionEnabled", wdtEnable,
+                                             "TimeoutAction", wdtTimeOutAction))
+                    {
+                        return;
+                    }
+                    setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction);
+                }
+
+                if (bootProps)
+                {
+                    std::optional<std::string> bootSource;
+                    std::optional<std::string> bootEnable;
+                    std::optional<std::string> automaticRetryConfig;
+
+                    if (!json_util::readJson(
+                            *bootProps, asyncResp->res,
+                            "BootSourceOverrideTarget", bootSource,
+                            "BootSourceOverrideEnabled", bootEnable,
+                            "AutomaticRetryConfig", automaticRetryConfig))
+                    {
+                        return;
+                    }
+                    if (bootSource || bootEnable)
+                    {
+                        setBootSourceProperties(asyncResp,
+                                                std::move(bootSource),
+                                                std::move(bootEnable));
+                    }
+                    if (automaticRetryConfig)
+                    {
+                        setAutomaticRetry(asyncResp, *automaticRetryConfig);
+                    }
+                }
+
+                if (locationIndicatorActive)
+                {
+                    setLocationIndicatorActive(asyncResp,
+                                               *locationIndicatorActive);
+                }
+
+                // TODO (Gunnar): Remove IndicatorLED after enough time has
+                // passed
+                if (indicatorLed)
+                {
+                    setIndicatorLedState(asyncResp, *indicatorLed);
+                    asyncResp->res.addHeader(
+                        boost::beast::http::field::warning,
+                        "299 - \"IndicatorLED is deprecated. Use "
+                        "LocationIndicatorActive instead.\"");
+                }
+
+                if (powerRestorePolicy)
+                {
+                    setPowerRestorePolicy(asyncResp, *powerRestorePolicy);
+                }
             });
-
-        getLocationIndicatorActive(asyncResp);
-        // TODO (Gunnar): Remove IndicatorLED after enough time has passed
-        getIndicatorLedState(asyncResp);
-        getComputerSystem(asyncResp, health);
-        getHostState(asyncResp);
-        getBootProperties(asyncResp);
-        getBootProgress(asyncResp);
-        getPCIeDeviceList(asyncResp, "PCIeDevices");
-        getHostWatchdogTimer(asyncResp);
-        getPowerRestorePolicy(asyncResp);
-        getAutomaticRetry(asyncResp);
-        getLastResetTime(asyncResp);
-#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
-        getProvisioningStatus(asyncResp);
-#endif
-    }
-
-    void doPatch(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                 const crow::Request& req,
-                 const std::vector<std::string>&) override
-    {
-        std::optional<bool> locationIndicatorActive;
-        std::optional<std::string> indicatorLed;
-        std::optional<nlohmann::json> bootProps;
-        std::optional<nlohmann::json> wdtTimerProps;
-        std::optional<std::string> assetTag;
-        std::optional<std::string> powerRestorePolicy;
-
-        if (!json_util::readJson(
-                req, asyncResp->res, "IndicatorLED", indicatorLed,
-                "LocationIndicatorActive", locationIndicatorActive, "Boot",
-                bootProps, "WatchdogTimer", wdtTimerProps, "PowerRestorePolicy",
-                powerRestorePolicy, "AssetTag", assetTag))
-        {
-            return;
-        }
-
-        asyncResp->res.result(boost::beast::http::status::no_content);
-
-        if (assetTag)
-        {
-            setAssetTag(asyncResp, *assetTag);
-        }
-
-        if (wdtTimerProps)
-        {
-            std::optional<bool> wdtEnable;
-            std::optional<std::string> wdtTimeOutAction;
-
-            if (!json_util::readJson(*wdtTimerProps, asyncResp->res,
-                                     "FunctionEnabled", wdtEnable,
-                                     "TimeoutAction", wdtTimeOutAction))
-            {
-                return;
-            }
-            setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction);
-        }
-
-        if (bootProps)
-        {
-            std::optional<std::string> bootSource;
-            std::optional<std::string> bootEnable;
-            std::optional<std::string> automaticRetryConfig;
-
-            if (!json_util::readJson(
-                    *bootProps, asyncResp->res, "BootSourceOverrideTarget",
-                    bootSource, "BootSourceOverrideEnabled", bootEnable,
-                    "AutomaticRetryConfig", automaticRetryConfig))
-            {
-                return;
-            }
-            if (bootSource || bootEnable)
-            {
-                setBootSourceProperties(asyncResp, std::move(bootSource),
-                                        std::move(bootEnable));
-            }
-            if (automaticRetryConfig)
-            {
-                setAutomaticRetry(asyncResp, *automaticRetryConfig);
-            }
-        }
-
-        if (locationIndicatorActive)
-        {
-            setLocationIndicatorActive(asyncResp, *locationIndicatorActive);
-        }
-
-        // TODO (Gunnar): Remove IndicatorLED after enough time has passed
-        if (indicatorLed)
-        {
-            setIndicatorLedState(asyncResp, *indicatorLed);
-            asyncResp->res.addHeader(boost::beast::http::field::warning,
-                                     "299 - \"IndicatorLED is deprecated. Use "
-                                     "LocationIndicatorActive instead.\"");
-        }
-
-        if (powerRestorePolicy)
-        {
-            setPowerRestorePolicy(asyncResp, *powerRestorePolicy);
-        }
-    }
-};
+}
 
 /**
  * SystemResetActionInfo derived class for delivering Computer Systems
  * ResetType AllowableValues using ResetInfo schema.
  */
-class SystemResetActionInfo : public Node
+inline void requestRoutesSystemResetActionInfo(App& app)
 {
-  public:
-    /*
-     * Default Constructor
-     */
-    SystemResetActionInfo(App& app) :
-        Node(app, "/redfish/v1/Systems/system/ResetActionInfo/")
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
-    }
 
-  private:
     /**
      * Functions triggers appropriate requests on DBus
      */
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&, const std::vector<std::string>&) override
-    {
-        asyncResp->res.jsonValue = {
-            {"@odata.type", "#ActionInfo.v1_1_2.ActionInfo"},
-            {"@odata.id", "/redfish/v1/Systems/system/ResetActionInfo"},
-            {"Name", "Reset Action Info"},
-            {"Id", "ResetActionInfo"},
-            {"Parameters",
-             {{{"Name", "ResetType"},
-               {"Required", true},
-               {"DataType", "String"},
-               {"AllowableValues",
-                {"On", "ForceOff", "ForceOn", "ForceRestart", "GracefulRestart",
-                 "GracefulShutdown", "PowerCycle", "Nmi"}}}}}};
-    }
-};
+    BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/ResetActionInfo/")
+        .privileges({"Login"})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                asyncResp->res.jsonValue = {
+                    {"@odata.type", "#ActionInfo.v1_1_2.ActionInfo"},
+                    {"@odata.id", "/redfish/v1/Systems/system/ResetActionInfo"},
+                    {"Name", "Reset Action Info"},
+                    {"Id", "ResetActionInfo"},
+                    {"Parameters",
+                     {{{"Name", "ResetType"},
+                       {"Required", true},
+                       {"DataType", "String"},
+                       {"AllowableValues",
+                        {"On", "ForceOff", "ForceOn", "ForceRestart",
+                         "GracefulRestart", "GracefulShutdown", "PowerCycle",
+                         "Nmi"}}}}}};
+            });
+}
 } // namespace redfish
diff --git a/redfish-core/lib/task.hpp b/redfish-core/lib/task.hpp
index 275806f..308a699 100644
--- a/redfish-core/lib/task.hpp
+++ b/redfish-core/lib/task.hpp
@@ -15,8 +15,7 @@
 */
 #pragma once
 
-#include "node.hpp"
-
+#include <app.hpp>
 #include <boost/asio/post.hpp>
 #include <boost/asio/steady_timer.hpp>
 #include <boost/container/flat_map.hpp>
@@ -314,223 +313,171 @@
 
 } // namespace task
 
-class TaskMonitor : public Node
+inline void requestRoutesTaskMonitor(App& app)
 {
-  public:
-    TaskMonitor(App& app) :
-        Node((app), "/redfish/v1/TaskService/Tasks/<str>/Monitor/",
-             std::string())
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-    }
+    BMCWEB_ROUTE(app, "/redfish/v1/TaskService/Tasks/<str>/Monitor/")
+        .privileges({"Login"})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+               const std::string& strParam) {
+                auto find = std::find_if(
+                    task::tasks.begin(), task::tasks.end(),
+                    [&strParam](const std::shared_ptr<task::TaskData>& task) {
+                        if (!task)
+                        {
+                            return false;
+                        }
 
-  private:
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&,
-               const std::vector<std::string>& params) override
-    {
+                        // we compare against the string version as on failure
+                        // strtoul returns 0
+                        return std::to_string(task->index) == strParam;
+                    });
 
-        if (params.size() != 1)
-        {
-            messages::internalError(asyncResp->res);
-            return;
-        }
-
-        const std::string& strParam = params[0];
-        auto find = std::find_if(
-            task::tasks.begin(), task::tasks.end(),
-            [&strParam](const std::shared_ptr<task::TaskData>& task) {
-                if (!task)
+                if (find == task::tasks.end())
                 {
-                    return false;
+                    messages::resourceNotFound(asyncResp->res, "Monitor",
+                                               strParam);
+                    return;
+                }
+                std::shared_ptr<task::TaskData>& ptr = *find;
+                // monitor expires after 204
+                if (ptr->gave204)
+                {
+                    messages::resourceNotFound(asyncResp->res, "Monitor",
+                                               strParam);
+                    return;
+                }
+                ptr->populateResp(asyncResp->res);
+            });
+}
+
+inline void requestRoutesTask(App& app)
+{
+    BMCWEB_ROUTE(app, "/redfish/v1/TaskService/Tasks/<str>/")
+        .privileges({"Login"})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+               const std::string& strParam) {
+                auto find = std::find_if(
+                    task::tasks.begin(), task::tasks.end(),
+                    [&strParam](const std::shared_ptr<task::TaskData>& task) {
+                        if (!task)
+                        {
+                            return false;
+                        }
+
+                        // we compare against the string version as on failure
+                        // strtoul returns 0
+                        return std::to_string(task->index) == strParam;
+                    });
+
+                if (find == task::tasks.end())
+                {
+                    messages::resourceNotFound(asyncResp->res, "Tasks",
+                                               strParam);
+                    return;
                 }
 
-                // we compare against the string version as on failure strtoul
-                // returns 0
-                return std::to_string(task->index) == strParam;
-            });
+                std::shared_ptr<task::TaskData>& ptr = *find;
 
-        if (find == task::tasks.end())
-        {
-            messages::resourceNotFound(asyncResp->res, "Monitor", strParam);
-            return;
-        }
-        std::shared_ptr<task::TaskData>& ptr = *find;
-        // monitor expires after 204
-        if (ptr->gave204)
-        {
-            messages::resourceNotFound(asyncResp->res, "Monitor", strParam);
-            return;
-        }
-        ptr->populateResp(asyncResp->res);
-    }
-};
-
-class Task : public Node
-{
-  public:
-    Task(App& app) :
-        Node((app), "/redfish/v1/TaskService/Tasks/<str>/", std::string())
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-    }
-
-  private:
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&,
-               const std::vector<std::string>& params) override
-    {
-
-        if (params.size() != 1)
-        {
-            messages::internalError(asyncResp->res);
-            return;
-        }
-
-        const std::string& strParam = params[0];
-        auto find = std::find_if(
-            task::tasks.begin(), task::tasks.end(),
-            [&strParam](const std::shared_ptr<task::TaskData>& task) {
-                if (!task)
+                asyncResp->res.jsonValue["@odata.type"] = "#Task.v1_4_3.Task";
+                asyncResp->res.jsonValue["Id"] = strParam;
+                asyncResp->res.jsonValue["Name"] = "Task " + strParam;
+                asyncResp->res.jsonValue["TaskState"] = ptr->state;
+                asyncResp->res.jsonValue["StartTime"] =
+                    crow::utility::getDateTime(ptr->startTime);
+                if (ptr->endTime)
                 {
-                    return false;
+                    asyncResp->res.jsonValue["EndTime"] =
+                        crow::utility::getDateTime(*(ptr->endTime));
                 }
-
-                // we compare against the string version as on failure strtoul
-                // returns 0
-                return std::to_string(task->index) == strParam;
+                asyncResp->res.jsonValue["TaskStatus"] = ptr->status;
+                asyncResp->res.jsonValue["Messages"] = ptr->messages;
+                asyncResp->res.jsonValue["@odata.id"] =
+                    "/redfish/v1/TaskService/Tasks/" + strParam;
+                if (!ptr->gave204)
+                {
+                    asyncResp->res.jsonValue["TaskMonitor"] =
+                        "/redfish/v1/TaskService/Tasks/" + strParam +
+                        "/Monitor";
+                }
+                if (ptr->payload)
+                {
+                    const task::Payload& p = *(ptr->payload);
+                    asyncResp->res.jsonValue["Payload"] = {
+                        {"TargetUri", p.targetUri},
+                        {"HttpOperation", p.httpOperation},
+                        {"HttpHeaders", p.httpHeaders},
+                        {"JsonBody",
+                         p.jsonBody.dump(
+                             2, ' ', true,
+                             nlohmann::json::error_handler_t::replace)}};
+                }
+                asyncResp->res.jsonValue["PercentComplete"] =
+                    ptr->percentComplete;
             });
+}
 
-        if (find == task::tasks.end())
-        {
-            messages::resourceNotFound(asyncResp->res, "Tasks", strParam);
-            return;
-        }
-
-        std::shared_ptr<task::TaskData>& ptr = *find;
-
-        asyncResp->res.jsonValue["@odata.type"] = "#Task.v1_4_3.Task";
-        asyncResp->res.jsonValue["Id"] = strParam;
-        asyncResp->res.jsonValue["Name"] = "Task " + strParam;
-        asyncResp->res.jsonValue["TaskState"] = ptr->state;
-        asyncResp->res.jsonValue["StartTime"] =
-            crow::utility::getDateTime(ptr->startTime);
-        if (ptr->endTime)
-        {
-            asyncResp->res.jsonValue["EndTime"] =
-                crow::utility::getDateTime(*(ptr->endTime));
-        }
-        asyncResp->res.jsonValue["TaskStatus"] = ptr->status;
-        asyncResp->res.jsonValue["Messages"] = ptr->messages;
-        asyncResp->res.jsonValue["@odata.id"] =
-            "/redfish/v1/TaskService/Tasks/" + strParam;
-        if (!ptr->gave204)
-        {
-            asyncResp->res.jsonValue["TaskMonitor"] =
-                "/redfish/v1/TaskService/Tasks/" + strParam + "/Monitor";
-        }
-        if (ptr->payload)
-        {
-            const task::Payload& p = *(ptr->payload);
-            asyncResp->res.jsonValue["Payload"] = {
-                {"TargetUri", p.targetUri},
-                {"HttpOperation", p.httpOperation},
-                {"HttpHeaders", p.httpHeaders},
-                {"JsonBody",
-                 p.jsonBody.dump(2, ' ', true,
-                                 nlohmann::json::error_handler_t::replace)}};
-        }
-        asyncResp->res.jsonValue["PercentComplete"] = ptr->percentComplete;
-    }
-};
-
-class TaskCollection : public Node
+inline void requestRoutesTaskCollection(App& app)
 {
-  public:
-    TaskCollection(App& app) : Node(app, "/redfish/v1/TaskService/Tasks/")
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-    }
+    BMCWEB_ROUTE(app, "/redfish/v1/TaskService/Tasks/")
+        .privileges({"Login"})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                asyncResp->res.jsonValue["@odata.type"] =
+                    "#TaskCollection.TaskCollection";
+                asyncResp->res.jsonValue["@odata.id"] =
+                    "/redfish/v1/TaskService/Tasks";
+                asyncResp->res.jsonValue["Name"] = "Task Collection";
+                asyncResp->res.jsonValue["Members@odata.count"] =
+                    task::tasks.size();
+                nlohmann::json& members = asyncResp->res.jsonValue["Members"];
+                members = nlohmann::json::array();
 
-  private:
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&, const std::vector<std::string>&) override
-    {
+                for (const std::shared_ptr<task::TaskData>& task : task::tasks)
+                {
+                    if (task == nullptr)
+                    {
+                        continue; // shouldn't be possible
+                    }
+                    members.emplace_back(nlohmann::json{
+                        {"@odata.id", "/redfish/v1/TaskService/Tasks/" +
+                                          std::to_string(task->index)}});
+                }
+            });
+}
 
-        asyncResp->res.jsonValue["@odata.type"] =
-            "#TaskCollection.TaskCollection";
-        asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/TaskService/Tasks";
-        asyncResp->res.jsonValue["Name"] = "Task Collection";
-        asyncResp->res.jsonValue["Members@odata.count"] = task::tasks.size();
-        nlohmann::json& members = asyncResp->res.jsonValue["Members"];
-        members = nlohmann::json::array();
-
-        for (const std::shared_ptr<task::TaskData>& task : task::tasks)
-        {
-            if (task == nullptr)
-            {
-                continue; // shouldn't be possible
-            }
-            members.emplace_back(
-                nlohmann::json{{"@odata.id", "/redfish/v1/TaskService/Tasks/" +
-                                                 std::to_string(task->index)}});
-        }
-    }
-};
-
-class TaskService : public Node
+inline void requestRoutesTaskService(App& app)
 {
-  public:
-    TaskService(App& app) : Node(app, "/redfish/v1/TaskService/")
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-    }
+    BMCWEB_ROUTE(app, "/redfish/v1/TaskService/")
+        .privileges({"Login"})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                asyncResp->res.jsonValue["@odata.type"] =
+                    "#TaskService.v1_1_4.TaskService";
+                asyncResp->res.jsonValue["@odata.id"] =
+                    "/redfish/v1/TaskService";
+                asyncResp->res.jsonValue["Name"] = "Task Service";
+                asyncResp->res.jsonValue["Id"] = "TaskService";
+                asyncResp->res.jsonValue["DateTime"] =
+                    crow::utility::dateTimeNow();
+                asyncResp->res.jsonValue["CompletedTaskOverWritePolicy"] =
+                    "Oldest";
 
-  private:
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&, const std::vector<std::string>&) override
-    {
-        asyncResp->res.jsonValue["@odata.type"] =
-            "#TaskService.v1_1_4.TaskService";
-        asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/TaskService";
-        asyncResp->res.jsonValue["Name"] = "Task Service";
-        asyncResp->res.jsonValue["Id"] = "TaskService";
-        asyncResp->res.jsonValue["DateTime"] = crow::utility::dateTimeNow();
-        asyncResp->res.jsonValue["CompletedTaskOverWritePolicy"] = "Oldest";
+                asyncResp->res.jsonValue["LifeCycleEventOnTaskStateChange"] =
+                    true;
 
-        asyncResp->res.jsonValue["LifeCycleEventOnTaskStateChange"] = true;
-
-        auto health = std::make_shared<HealthPopulate>(asyncResp);
-        health->populate();
-        asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
-        asyncResp->res.jsonValue["ServiceEnabled"] = true;
-        asyncResp->res.jsonValue["Tasks"] = {
-            {"@odata.id", "/redfish/v1/TaskService/Tasks"}};
-    }
-};
+                auto health = std::make_shared<HealthPopulate>(asyncResp);
+                health->populate();
+                asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
+                asyncResp->res.jsonValue["ServiceEnabled"] = true;
+                asyncResp->res.jsonValue["Tasks"] = {
+                    {"@odata.id", "/redfish/v1/TaskService/Tasks"}};
+            });
+}
 
 } // namespace redfish
diff --git a/redfish-core/lib/telemetry_service.hpp b/redfish-core/lib/telemetry_service.hpp
index 9ec0737..e6f5b0f 100644
--- a/redfish-core/lib/telemetry_service.hpp
+++ b/redfish-core/lib/telemetry_service.hpp
@@ -1,90 +1,82 @@
 #pragma once
 
-#include "node.hpp"
 #include "utils/telemetry_utils.hpp"
 
+#include <app.hpp>
+
 #include <variant>
 
 namespace redfish
 {
 
-class TelemetryService : public Node
+inline void requestRoutesTelemetryService(App& app)
 {
-  public:
-    TelemetryService(App& app) : Node(app, "/redfish/v1/TelemetryService/")
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-    }
+    BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/")
+        .privileges({"Login"})
+        .methods(
+            boost::beast::http::verb::
+                get)([](const crow::Request&,
+                        const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+            asyncResp->res.jsonValue["@odata.type"] =
+                "#TelemetryService.v1_2_1.TelemetryService";
+            asyncResp->res.jsonValue["@odata.id"] =
+                "/redfish/v1/TelemetryService";
+            asyncResp->res.jsonValue["Id"] = "TelemetryService";
+            asyncResp->res.jsonValue["Name"] = "Telemetry Service";
 
-  private:
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&, const std::vector<std::string>&) override
-    {
-        asyncResp->res.jsonValue["@odata.type"] =
-            "#TelemetryService.v1_2_1.TelemetryService";
-        asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/TelemetryService";
-        asyncResp->res.jsonValue["Id"] = "TelemetryService";
-        asyncResp->res.jsonValue["Name"] = "Telemetry Service";
+            asyncResp->res.jsonValue["MetricReportDefinitions"]["@odata.id"] =
+                "/redfish/v1/TelemetryService/MetricReportDefinitions";
+            asyncResp->res.jsonValue["MetricReports"]["@odata.id"] =
+                "/redfish/v1/TelemetryService/MetricReports";
 
-        asyncResp->res.jsonValue["MetricReportDefinitions"]["@odata.id"] =
-            "/redfish/v1/TelemetryService/MetricReportDefinitions";
-        asyncResp->res.jsonValue["MetricReports"]["@odata.id"] =
-            "/redfish/v1/TelemetryService/MetricReports";
-
-        crow::connections::systemBus->async_method_call(
-            [asyncResp](
-                const boost::system::error_code ec,
-                const std::vector<std::pair<
-                    std::string, std::variant<uint32_t, uint64_t>>>& ret) {
-                if (ec == boost::system::errc::host_unreachable)
-                {
-                    asyncResp->res.jsonValue["Status"]["State"] = "Absent";
-                    return;
-                }
-                if (ec)
-                {
-                    BMCWEB_LOG_ERROR << "respHandler DBus error " << ec;
-                    messages::internalError(asyncResp->res);
-                    return;
-                }
-
-                asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
-
-                const size_t* maxReports = nullptr;
-                const uint64_t* minInterval = nullptr;
-                for (const auto& [key, var] : ret)
-                {
-                    if (key == "MaxReports")
+            crow::connections::systemBus->async_method_call(
+                [asyncResp](
+                    const boost::system::error_code ec,
+                    const std::vector<std::pair<
+                        std::string, std::variant<uint32_t, uint64_t>>>& ret) {
+                    if (ec == boost::system::errc::host_unreachable)
                     {
-                        maxReports = std::get_if<size_t>(&var);
+                        asyncResp->res.jsonValue["Status"]["State"] = "Absent";
+                        return;
                     }
-                    else if (key == "MinInterval")
+                    if (ec)
                     {
-                        minInterval = std::get_if<uint64_t>(&var);
+                        BMCWEB_LOG_ERROR << "respHandler DBus error " << ec;
+                        messages::internalError(asyncResp->res);
+                        return;
                     }
-                }
-                if (!maxReports || !minInterval)
-                {
-                    BMCWEB_LOG_ERROR
-                        << "Property type mismatch or property is missing";
-                    messages::internalError(asyncResp->res);
-                    return;
-                }
 
-                asyncResp->res.jsonValue["MaxReports"] = *maxReports;
-                asyncResp->res.jsonValue["MinCollectionInterval"] =
-                    time_utils::toDurationString(std::chrono::milliseconds(
-                        static_cast<time_t>(*minInterval)));
-            },
-            telemetry::service, "/xyz/openbmc_project/Telemetry/Reports",
-            "org.freedesktop.DBus.Properties", "GetAll",
-            "xyz.openbmc_project.Telemetry.ReportManager");
-    }
-};
+                    asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
+
+                    const size_t* maxReports = nullptr;
+                    const uint64_t* minInterval = nullptr;
+                    for (const auto& [key, var] : ret)
+                    {
+                        if (key == "MaxReports")
+                        {
+                            maxReports = std::get_if<size_t>(&var);
+                        }
+                        else if (key == "MinInterval")
+                        {
+                            minInterval = std::get_if<uint64_t>(&var);
+                        }
+                    }
+                    if (!maxReports || !minInterval)
+                    {
+                        BMCWEB_LOG_ERROR
+                            << "Property type mismatch or property is missing";
+                        messages::internalError(asyncResp->res);
+                        return;
+                    }
+
+                    asyncResp->res.jsonValue["MaxReports"] = *maxReports;
+                    asyncResp->res.jsonValue["MinCollectionInterval"] =
+                        time_utils::toDurationString(std::chrono::milliseconds(
+                            static_cast<time_t>(*minInterval)));
+                },
+                telemetry::service, "/xyz/openbmc_project/Telemetry/Reports",
+                "org.freedesktop.DBus.Properties", "GetAll",
+                "xyz.openbmc_project.Telemetry.ReportManager");
+        });
+}
 } // namespace redfish
diff --git a/redfish-core/lib/thermal.hpp b/redfish-core/lib/thermal.hpp
index e064f1f..078da9c 100644
--- a/redfish-core/lib/thermal.hpp
+++ b/redfish-core/lib/thermal.hpp
@@ -15,106 +15,85 @@
 */
 #pragma once
 
-#include "node.hpp"
 #include "sensors.hpp"
 
+#include <app.hpp>
+
 namespace redfish
 {
 
-class Thermal : public Node
+inline void requestRoutesThermal(App& app)
 {
-  public:
-    Thermal(App& app) :
-        Node((app), "/redfish/v1/Chassis/<str>/Thermal/", std::string())
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-    }
+    BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/Thermal/")
+        .privileges({"Login"})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+               const std::string& chassisName) {
+                auto thermalPaths =
+                    sensors::dbus::paths.find(sensors::node::thermal);
+                if (thermalPaths == sensors::dbus::paths.end())
+                {
+                    messages::internalError(asyncResp->res);
+                    return;
+                }
 
-  private:
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&,
-               const std::vector<std::string>& params) override
-    {
-        if (params.size() != 1)
-        {
-            messages::internalError(asyncResp->res);
+                auto sensorAsyncResp = std::make_shared<SensorsAsyncResp>(
+                    asyncResp, chassisName, thermalPaths->second,
+                    sensors::node::thermal);
 
-            return;
-        }
+                // TODO Need to get Chassis Redundancy information.
+                getChassisData(sensorAsyncResp);
+            });
 
-        auto thermalPaths = sensors::dbus::paths.find(sensors::node::thermal);
-        if (thermalPaths == sensors::dbus::paths.end())
-        {
-            messages::internalError(asyncResp->res);
-            return;
-        }
+    BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/Thermal/")
+        .privileges({"ConfigureManager"})
+        .methods(boost::beast::http::verb::patch)(
+            [](const crow::Request& req,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+               const std::string& chassisName) {
+                auto thermalPaths =
+                    sensors::dbus::paths.find(sensors::node::thermal);
+                if (thermalPaths == sensors::dbus::paths.end())
+                {
+                    messages::internalError(asyncResp->res);
+                    return;
+                }
 
-        const std::string& chassisName = params[0];
-        auto sensorAsyncResp = std::make_shared<SensorsAsyncResp>(
-            asyncResp, chassisName, thermalPaths->second,
-            sensors::node::thermal);
+                std::optional<std::vector<nlohmann::json>>
+                    temperatureCollections;
+                std::optional<std::vector<nlohmann::json>> fanCollections;
+                std::unordered_map<std::string, std::vector<nlohmann::json>>
+                    allCollections;
 
-        // TODO Need to get Chassis Redundancy information.
-        getChassisData(sensorAsyncResp);
-    }
-    void doPatch(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                 const crow::Request& req,
-                 const std::vector<std::string>& params) override
-    {
-        if (params.size() != 1)
-        {
+                auto sensorsAsyncResp = std::make_shared<SensorsAsyncResp>(
+                    asyncResp, chassisName, thermalPaths->second,
+                    sensors::node::thermal);
 
-            messages::internalError(asyncResp->res);
-            return;
-        }
-
-        auto thermalPaths = sensors::dbus::paths.find(sensors::node::thermal);
-        if (thermalPaths == sensors::dbus::paths.end())
-        {
-            messages::internalError(asyncResp->res);
-            return;
-        }
-
-        const std::string& chassisName = params[0];
-        std::optional<std::vector<nlohmann::json>> temperatureCollections;
-        std::optional<std::vector<nlohmann::json>> fanCollections;
-        std::unordered_map<std::string, std::vector<nlohmann::json>>
-            allCollections;
-
-        auto sensorsAsyncResp = std::make_shared<SensorsAsyncResp>(
-            asyncResp, chassisName, thermalPaths->second,
-            sensors::node::thermal);
-
-        if (!json_util::readJson(req, sensorsAsyncResp->asyncResp->res,
-                                 "Temperatures", temperatureCollections, "Fans",
-                                 fanCollections))
-        {
-            return;
-        }
-        if (!temperatureCollections && !fanCollections)
-        {
-            messages::resourceNotFound(sensorsAsyncResp->asyncResp->res,
-                                       "Thermal", "Temperatures / Voltages");
-            return;
-        }
-        if (temperatureCollections)
-        {
-            allCollections.emplace("Temperatures",
-                                   *std::move(temperatureCollections));
-        }
-        if (fanCollections)
-        {
-            allCollections.emplace("Fans", *std::move(fanCollections));
-        }
-
-        checkAndDoSensorsOverride(sensorsAsyncResp, allCollections);
-    }
-};
+                if (!json_util::readJson(req, sensorsAsyncResp->asyncResp->res,
+                                         "Temperatures", temperatureCollections,
+                                         "Fans", fanCollections))
+                {
+                    return;
+                }
+                if (!temperatureCollections && !fanCollections)
+                {
+                    messages::resourceNotFound(sensorsAsyncResp->asyncResp->res,
+                                               "Thermal",
+                                               "Temperatures / Voltages");
+                    return;
+                }
+                if (temperatureCollections)
+                {
+                    allCollections.emplace("Temperatures",
+                                           *std::move(temperatureCollections));
+                }
+                if (fanCollections)
+                {
+                    allCollections.emplace("Fans", *std::move(fanCollections));
+                }
+                checkAndDoSensorsOverride(sensorsAsyncResp, allCollections);
+            });
+}
 
 } // namespace redfish
diff --git a/redfish-core/lib/update_service.hpp b/redfish-core/lib/update_service.hpp
index 9f6c6f9..bfab6fb 100644
--- a/redfish-core/lib/update_service.hpp
+++ b/redfish-core/lib/update_service.hpp
@@ -15,8 +15,7 @@
 */
 #pragma once
 
-#include "node.hpp"
-
+#include <app.hpp>
 #include <boost/container/flat_map.hpp>
 #include <utils/fw_utils.hpp>
 
@@ -33,14 +32,14 @@
 // Timer for software available
 static std::unique_ptr<boost::asio::steady_timer> fwAvailableTimer;
 
-static void cleanUp()
+inline static void cleanUp()
 {
     fwUpdateInProgress = false;
     fwUpdateMatcher = nullptr;
     fwUpdateErrorMatcher = nullptr;
 }
-static void activateImage(const std::string& objPath,
-                          const std::string& service)
+inline static void activateImage(const std::string& objPath,
+                                 const std::string& service)
 {
     BMCWEB_LOG_DEBUG << "Activate image for " << objPath << " " << service;
     crow::connections::systemBus->async_method_call(
@@ -383,589 +382,555 @@
  * UpdateServiceActionsSimpleUpdate class supports handle POST method for
  * SimpleUpdate action.
  */
-class UpdateServiceActionsSimpleUpdate : public Node
+inline void requestRoutesUpdateServiceActionsSimpleUpdate(App& app)
 {
-  public:
-    UpdateServiceActionsSimpleUpdate(App& app) :
-        Node(app,
-             "/redfish/v1/UpdateService/Actions/UpdateService.SimpleUpdate/")
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-            {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
-    }
+    BMCWEB_ROUTE(
+        app, "/redfish/v1/UpdateService/Actions/UpdateService.SimpleUpdate/")
+        .privileges({"ConfigureComponents"})
+        .methods(
+            boost::beast::http::verb::
+                post)([](const crow::Request& req,
+                         const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+            std::optional<std::string> transferProtocol;
+            std::string imageURI;
 
-  private:
-    void doPost(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                const crow::Request& req,
-                const std::vector<std::string>&) override
-    {
-        std::optional<std::string> transferProtocol;
-        std::string imageURI;
+            BMCWEB_LOG_DEBUG << "Enter UpdateService.SimpleUpdate doPost";
 
-        BMCWEB_LOG_DEBUG << "Enter UpdateService.SimpleUpdate doPost";
+            // User can pass in both TransferProtocol and ImageURI parameters or
+            // they can pass in just the ImageURI with the transfer protocol
+            // embedded within it.
+            // 1) TransferProtocol:TFTP ImageURI:1.1.1.1/myfile.bin
+            // 2) ImageURI:tftp://1.1.1.1/myfile.bin
 
-        // User can pass in both TransferProtocol and ImageURI parameters or
-        // they can pass in just the ImageURI with the transfer protocol
-        // embedded within it.
-        // 1) TransferProtocol:TFTP ImageURI:1.1.1.1/myfile.bin
-        // 2) ImageURI:tftp://1.1.1.1/myfile.bin
+            if (!json_util::readJson(req, asyncResp->res, "TransferProtocol",
+                                     transferProtocol, "ImageURI", imageURI))
+            {
+                BMCWEB_LOG_DEBUG
+                    << "Missing TransferProtocol or ImageURI parameter";
+                return;
+            }
+            if (!transferProtocol)
+            {
+                // Must be option 2
+                // Verify ImageURI has transfer protocol in it
+                size_t separator = imageURI.find(':');
+                if ((separator == std::string::npos) ||
+                    ((separator + 1) > imageURI.size()))
+                {
+                    messages::actionParameterValueTypeError(
+                        asyncResp->res, imageURI, "ImageURI",
+                        "UpdateService.SimpleUpdate");
+                    BMCWEB_LOG_ERROR << "ImageURI missing transfer protocol: "
+                                     << imageURI;
+                    return;
+                }
+                transferProtocol = imageURI.substr(0, separator);
+                // Ensure protocol is upper case for a common comparison path
+                // below
+                boost::to_upper(*transferProtocol);
+                BMCWEB_LOG_DEBUG << "Encoded transfer protocol "
+                                 << *transferProtocol;
 
-        if (!json_util::readJson(req, asyncResp->res, "TransferProtocol",
-                                 transferProtocol, "ImageURI", imageURI))
-        {
-            BMCWEB_LOG_DEBUG
-                << "Missing TransferProtocol or ImageURI parameter";
-            return;
-        }
-        if (!transferProtocol)
-        {
-            // Must be option 2
-            // Verify ImageURI has transfer protocol in it
-            size_t separator = imageURI.find(':');
+                // Adjust imageURI to not have the protocol on it for parsing
+                // below
+                // ex. tftp://1.1.1.1/myfile.bin -> 1.1.1.1/myfile.bin
+                imageURI = imageURI.substr(separator + 3);
+                BMCWEB_LOG_DEBUG << "Adjusted imageUri " << imageURI;
+            }
+
+            // OpenBMC currently only supports TFTP
+            if (*transferProtocol != "TFTP")
+            {
+                messages::actionParameterNotSupported(
+                    asyncResp->res, "TransferProtocol",
+                    "UpdateService.SimpleUpdate");
+                BMCWEB_LOG_ERROR << "Request incorrect protocol parameter: "
+                                 << *transferProtocol;
+                return;
+            }
+
+            // Format should be <IP or Hostname>/<file> for imageURI
+            size_t separator = imageURI.find('/');
             if ((separator == std::string::npos) ||
                 ((separator + 1) > imageURI.size()))
             {
                 messages::actionParameterValueTypeError(
                     asyncResp->res, imageURI, "ImageURI",
                     "UpdateService.SimpleUpdate");
-                BMCWEB_LOG_ERROR << "ImageURI missing transfer protocol: "
-                                 << imageURI;
-                return;
-            }
-            transferProtocol = imageURI.substr(0, separator);
-            // Ensure protocol is upper case for a common comparison path below
-            boost::to_upper(*transferProtocol);
-            BMCWEB_LOG_DEBUG << "Encoded transfer protocol "
-                             << *transferProtocol;
-
-            // Adjust imageURI to not have the protocol on it for parsing
-            // below
-            // ex. tftp://1.1.1.1/myfile.bin -> 1.1.1.1/myfile.bin
-            imageURI = imageURI.substr(separator + 3);
-            BMCWEB_LOG_DEBUG << "Adjusted imageUri " << imageURI;
-        }
-
-        // OpenBMC currently only supports TFTP
-        if (*transferProtocol != "TFTP")
-        {
-            messages::actionParameterNotSupported(asyncResp->res,
-                                                  "TransferProtocol",
-                                                  "UpdateService.SimpleUpdate");
-            BMCWEB_LOG_ERROR << "Request incorrect protocol parameter: "
-                             << *transferProtocol;
-            return;
-        }
-
-        // Format should be <IP or Hostname>/<file> for imageURI
-        size_t separator = imageURI.find('/');
-        if ((separator == std::string::npos) ||
-            ((separator + 1) > imageURI.size()))
-        {
-            messages::actionParameterValueTypeError(
-                asyncResp->res, imageURI, "ImageURI",
-                "UpdateService.SimpleUpdate");
-            BMCWEB_LOG_ERROR << "Invalid ImageURI: " << imageURI;
-            return;
-        }
-
-        std::string tftpServer = imageURI.substr(0, separator);
-        std::string fwFile = imageURI.substr(separator + 1);
-        BMCWEB_LOG_DEBUG << "Server: " << tftpServer + " File: " << fwFile;
-
-        // Setup callback for when new software detected
-        // Give TFTP 10 minutes to complete
-        monitorForSoftwareAvailable(
-            asyncResp, req,
-            "/redfish/v1/UpdateService/Actions/UpdateService.SimpleUpdate",
-            600);
-
-        // TFTP can take up to 10 minutes depending on image size and
-        // connection speed. Return to caller as soon as the TFTP operation
-        // has been started. The callback above will ensure the activate
-        // is started once the download has completed
-        redfish::messages::success(asyncResp->res);
-
-        // Call TFTP service
-        crow::connections::systemBus->async_method_call(
-            [](const boost::system::error_code ec) {
-                if (ec)
-                {
-                    // messages::internalError(asyncResp->res);
-                    cleanUp();
-                    BMCWEB_LOG_DEBUG << "error_code = " << ec;
-                    BMCWEB_LOG_DEBUG << "error msg = " << ec.message();
-                }
-                else
-                {
-                    BMCWEB_LOG_DEBUG << "Call to DownloaViaTFTP Success";
-                }
-            },
-            "xyz.openbmc_project.Software.Download",
-            "/xyz/openbmc_project/software", "xyz.openbmc_project.Common.TFTP",
-            "DownloadViaTFTP", fwFile, tftpServer);
-
-        BMCWEB_LOG_DEBUG << "Exit UpdateService.SimpleUpdate doPost";
-    }
-};
-
-class UpdateService : public Node
-{
-  public:
-    UpdateService(App& app) : Node(app, "/redfish/v1/UpdateService/")
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
-    }
-
-  private:
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&, const std::vector<std::string>&) override
-    {
-        asyncResp->res.jsonValue["@odata.type"] =
-            "#UpdateService.v1_4_0.UpdateService";
-        asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/UpdateService";
-        asyncResp->res.jsonValue["Id"] = "UpdateService";
-        asyncResp->res.jsonValue["Description"] = "Service for Software Update";
-        asyncResp->res.jsonValue["Name"] = "Update Service";
-        asyncResp->res.jsonValue["HttpPushUri"] = "/redfish/v1/UpdateService";
-        // UpdateService cannot be disabled
-        asyncResp->res.jsonValue["ServiceEnabled"] = true;
-        asyncResp->res.jsonValue["FirmwareInventory"] = {
-            {"@odata.id", "/redfish/v1/UpdateService/FirmwareInventory"}};
-#ifdef BMCWEB_INSECURE_ENABLE_REDFISH_FW_TFTP_UPDATE
-        // Update Actions object.
-        nlohmann::json& updateSvcSimpleUpdate =
-            asyncResp->res.jsonValue["Actions"]["#UpdateService.SimpleUpdate"];
-        updateSvcSimpleUpdate["target"] =
-            "/redfish/v1/UpdateService/Actions/UpdateService.SimpleUpdate";
-        updateSvcSimpleUpdate["TransferProtocol@Redfish.AllowableValues"] = {
-            "TFTP"};
-#endif
-        // Get the current ApplyTime value
-        crow::connections::systemBus->async_method_call(
-            [asyncResp](const boost::system::error_code ec,
-                        const std::variant<std::string>& applyTime) {
-                if (ec)
-                {
-                    BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
-                    messages::internalError(asyncResp->res);
-                    return;
-                }
-
-                const std::string* s = std::get_if<std::string>(&applyTime);
-                if (s == nullptr)
-                {
-                    return;
-                }
-                // Store the ApplyTime Value
-                if (*s == "xyz.openbmc_project.Software.ApplyTime."
-                          "RequestedApplyTimes.Immediate")
-                {
-                    asyncResp->res
-                        .jsonValue["HttpPushUriOptions"]["HttpPushUriApplyTime"]
-                                  ["ApplyTime"] = "Immediate";
-                }
-                else if (*s == "xyz.openbmc_project.Software.ApplyTime."
-                               "RequestedApplyTimes.OnReset")
-                {
-                    asyncResp->res
-                        .jsonValue["HttpPushUriOptions"]["HttpPushUriApplyTime"]
-                                  ["ApplyTime"] = "OnReset";
-                }
-            },
-            "xyz.openbmc_project.Settings",
-            "/xyz/openbmc_project/software/apply_time",
-            "org.freedesktop.DBus.Properties", "Get",
-            "xyz.openbmc_project.Software.ApplyTime", "RequestedApplyTime");
-    }
-
-    void doPatch(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                 const crow::Request& req,
-                 const std::vector<std::string>&) override
-    {
-        BMCWEB_LOG_DEBUG << "doPatch...";
-
-        std::optional<nlohmann::json> pushUriOptions;
-        if (!json_util::readJson(req, asyncResp->res, "HttpPushUriOptions",
-                                 pushUriOptions))
-        {
-            return;
-        }
-
-        if (pushUriOptions)
-        {
-            std::optional<nlohmann::json> pushUriApplyTime;
-            if (!json_util::readJson(*pushUriOptions, asyncResp->res,
-                                     "HttpPushUriApplyTime", pushUriApplyTime))
-            {
+                BMCWEB_LOG_ERROR << "Invalid ImageURI: " << imageURI;
                 return;
             }
 
-            if (pushUriApplyTime)
-            {
-                std::optional<std::string> applyTime;
-                if (!json_util::readJson(*pushUriApplyTime, asyncResp->res,
-                                         "ApplyTime", applyTime))
-                {
-                    return;
-                }
+            std::string tftpServer = imageURI.substr(0, separator);
+            std::string fwFile = imageURI.substr(separator + 1);
+            BMCWEB_LOG_DEBUG << "Server: " << tftpServer + " File: " << fwFile;
 
-                if (applyTime)
-                {
-                    std::string applyTimeNewVal;
-                    if (applyTime == "Immediate")
+            // Setup callback for when new software detected
+            // Give TFTP 10 minutes to complete
+            monitorForSoftwareAvailable(
+                asyncResp, req,
+                "/redfish/v1/UpdateService/Actions/UpdateService.SimpleUpdate",
+                600);
+
+            // TFTP can take up to 10 minutes depending on image size and
+            // connection speed. Return to caller as soon as the TFTP operation
+            // has been started. The callback above will ensure the activate
+            // is started once the download has completed
+            redfish::messages::success(asyncResp->res);
+
+            // Call TFTP service
+            crow::connections::systemBus->async_method_call(
+                [](const boost::system::error_code ec) {
+                    if (ec)
                     {
-                        applyTimeNewVal =
-                            "xyz.openbmc_project.Software.ApplyTime."
-                            "RequestedApplyTimes.Immediate";
-                    }
-                    else if (applyTime == "OnReset")
-                    {
-                        applyTimeNewVal =
-                            "xyz.openbmc_project.Software.ApplyTime."
-                            "RequestedApplyTimes.OnReset";
+                        // messages::internalError(asyncResp->res);
+                        cleanUp();
+                        BMCWEB_LOG_DEBUG << "error_code = " << ec;
+                        BMCWEB_LOG_DEBUG << "error msg = " << ec.message();
                     }
                     else
                     {
-                        BMCWEB_LOG_INFO
-                            << "ApplyTime value is not in the list of "
-                               "acceptable values";
-                        messages::propertyValueNotInList(
-                            asyncResp->res, *applyTime, "ApplyTime");
+                        BMCWEB_LOG_DEBUG << "Call to DownloaViaTFTP Success";
+                    }
+                },
+                "xyz.openbmc_project.Software.Download",
+                "/xyz/openbmc_project/software",
+                "xyz.openbmc_project.Common.TFTP", "DownloadViaTFTP", fwFile,
+                tftpServer);
+
+            BMCWEB_LOG_DEBUG << "Exit UpdateService.SimpleUpdate doPost";
+        });
+}
+
+inline void requestRoutesUpdateService(App& app)
+{
+    BMCWEB_ROUTE(app, "/redfish/v1/UpdateService/")
+        .privileges({"Login"})
+        .methods(
+            boost::beast::http::verb::
+                get)([](const crow::Request&,
+                        const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+            asyncResp->res.jsonValue["@odata.type"] =
+                "#UpdateService.v1_4_0.UpdateService";
+            asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/UpdateService";
+            asyncResp->res.jsonValue["Id"] = "UpdateService";
+            asyncResp->res.jsonValue["Description"] =
+                "Service for Software Update";
+            asyncResp->res.jsonValue["Name"] = "Update Service";
+            asyncResp->res.jsonValue["HttpPushUri"] =
+                "/redfish/v1/UpdateService";
+            // UpdateService cannot be disabled
+            asyncResp->res.jsonValue["ServiceEnabled"] = true;
+            asyncResp->res.jsonValue["FirmwareInventory"] = {
+                {"@odata.id", "/redfish/v1/UpdateService/FirmwareInventory"}};
+#ifdef BMCWEB_INSECURE_ENABLE_REDFISH_FW_TFTP_UPDATE
+            // Update Actions object.
+            nlohmann::json& updateSvcSimpleUpdate =
+                asyncResp->res
+                    .jsonValue["Actions"]["#UpdateService.SimpleUpdate"];
+            updateSvcSimpleUpdate["target"] =
+                "/redfish/v1/UpdateService/Actions/UpdateService.SimpleUpdate";
+            updateSvcSimpleUpdate["TransferProtocol@Redfish.AllowableValues"] =
+                {"TFTP"};
+#endif
+            // Get the current ApplyTime value
+            crow::connections::systemBus->async_method_call(
+                [asyncResp](const boost::system::error_code ec,
+                            const std::variant<std::string>& applyTime) {
+                    if (ec)
+                    {
+                        BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
+                        messages::internalError(asyncResp->res);
                         return;
                     }
 
-                    // Set the requested image apply time value
-                    crow::connections::systemBus->async_method_call(
-                        [asyncResp](const boost::system::error_code ec) {
-                            if (ec)
-                            {
-                                BMCWEB_LOG_ERROR << "D-Bus responses error: "
-                                                 << ec;
-                                messages::internalError(asyncResp->res);
-                                return;
-                            }
-                            messages::success(asyncResp->res);
-                        },
-                        "xyz.openbmc_project.Settings",
-                        "/xyz/openbmc_project/software/apply_time",
-                        "org.freedesktop.DBus.Properties", "Set",
-                        "xyz.openbmc_project.Software.ApplyTime",
-                        "RequestedApplyTime",
-                        std::variant<std::string>{applyTimeNewVal});
-                }
-            }
-        }
-    }
+                    const std::string* s = std::get_if<std::string>(&applyTime);
+                    if (s == nullptr)
+                    {
+                        return;
+                    }
+                    // Store the ApplyTime Value
+                    if (*s == "xyz.openbmc_project.Software.ApplyTime."
+                              "RequestedApplyTimes.Immediate")
+                    {
+                        asyncResp->res
+                            .jsonValue["HttpPushUriOptions"]
+                                      ["HttpPushUriApplyTime"]["ApplyTime"] =
+                            "Immediate";
+                    }
+                    else if (*s == "xyz.openbmc_project.Software.ApplyTime."
+                                   "RequestedApplyTimes.OnReset")
+                    {
+                        asyncResp->res
+                            .jsonValue["HttpPushUriOptions"]
+                                      ["HttpPushUriApplyTime"]["ApplyTime"] =
+                            "OnReset";
+                    }
+                },
+                "xyz.openbmc_project.Settings",
+                "/xyz/openbmc_project/software/apply_time",
+                "org.freedesktop.DBus.Properties", "Get",
+                "xyz.openbmc_project.Software.ApplyTime", "RequestedApplyTime");
+        });
+    BMCWEB_ROUTE(app, "/redfish/v1/UpdateService/")
+        .privileges({"ConfigureComponents"})
+        .methods(boost::beast::http::verb::patch)(
+            [](const crow::Request& req,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                BMCWEB_LOG_DEBUG << "doPatch...";
 
-    void doPost(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                const crow::Request& req,
-                const std::vector<std::string>&) override
-    {
-        BMCWEB_LOG_DEBUG << "doPost...";
-
-        // Setup callback for when new software detected
-        monitorForSoftwareAvailable(asyncResp, req,
-                                    "/redfish/v1/UpdateService");
-
-        std::string filepath(
-            "/tmp/images/" +
-            boost::uuids::to_string(boost::uuids::random_generator()()));
-        BMCWEB_LOG_DEBUG << "Writing file to " << filepath;
-        std::ofstream out(filepath, std::ofstream::out | std::ofstream::binary |
-                                        std::ofstream::trunc);
-        out << req.body;
-        out.close();
-        BMCWEB_LOG_DEBUG << "file upload complete!!";
-    }
-};
-
-class SoftwareInventoryCollection : public Node
-{
-  public:
-    SoftwareInventoryCollection(App& app) :
-        Node(app, "/redfish/v1/UpdateService/FirmwareInventory/")
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
-    }
-
-  private:
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&, const std::vector<std::string>&) override
-    {
-        asyncResp->res.jsonValue["@odata.type"] =
-            "#SoftwareInventoryCollection.SoftwareInventoryCollection";
-        asyncResp->res.jsonValue["@odata.id"] =
-            "/redfish/v1/UpdateService/FirmwareInventory";
-        asyncResp->res.jsonValue["Name"] = "Software Inventory Collection";
-
-        crow::connections::systemBus->async_method_call(
-            [asyncResp](
-                const boost::system::error_code ec,
-                const std::vector<std::pair<
-                    std::string, std::vector<std::pair<
-                                     std::string, std::vector<std::string>>>>>&
-                    subtree) {
-                if (ec)
+                std::optional<nlohmann::json> pushUriOptions;
+                if (!json_util::readJson(req, asyncResp->res,
+                                         "HttpPushUriOptions", pushUriOptions))
                 {
-                    messages::internalError(asyncResp->res);
                     return;
                 }
-                asyncResp->res.jsonValue["Members"] = nlohmann::json::array();
-                asyncResp->res.jsonValue["Members@odata.count"] = 0;
 
-                for (auto& obj : subtree)
+                if (pushUriOptions)
                 {
-                    sdbusplus::message::object_path path(obj.first);
-                    std::string swId = path.filename();
-                    if (swId.empty())
+                    std::optional<nlohmann::json> pushUriApplyTime;
+                    if (!json_util::readJson(*pushUriOptions, asyncResp->res,
+                                             "HttpPushUriApplyTime",
+                                             pushUriApplyTime))
+                    {
+                        return;
+                    }
+
+                    if (pushUriApplyTime)
+                    {
+                        std::optional<std::string> applyTime;
+                        if (!json_util::readJson(*pushUriApplyTime,
+                                                 asyncResp->res, "ApplyTime",
+                                                 applyTime))
+                        {
+                            return;
+                        }
+
+                        if (applyTime)
+                        {
+                            std::string applyTimeNewVal;
+                            if (applyTime == "Immediate")
+                            {
+                                applyTimeNewVal =
+                                    "xyz.openbmc_project.Software.ApplyTime."
+                                    "RequestedApplyTimes.Immediate";
+                            }
+                            else if (applyTime == "OnReset")
+                            {
+                                applyTimeNewVal =
+                                    "xyz.openbmc_project.Software.ApplyTime."
+                                    "RequestedApplyTimes.OnReset";
+                            }
+                            else
+                            {
+                                BMCWEB_LOG_INFO
+                                    << "ApplyTime value is not in the list of "
+                                       "acceptable values";
+                                messages::propertyValueNotInList(
+                                    asyncResp->res, *applyTime, "ApplyTime");
+                                return;
+                            }
+
+                            // Set the requested image apply time value
+                            crow::connections::systemBus->async_method_call(
+                                [asyncResp](
+                                    const boost::system::error_code ec) {
+                                    if (ec)
+                                    {
+                                        BMCWEB_LOG_ERROR
+                                            << "D-Bus responses error: " << ec;
+                                        messages::internalError(asyncResp->res);
+                                        return;
+                                    }
+                                    messages::success(asyncResp->res);
+                                },
+                                "xyz.openbmc_project.Settings",
+                                "/xyz/openbmc_project/software/apply_time",
+                                "org.freedesktop.DBus.Properties", "Set",
+                                "xyz.openbmc_project.Software.ApplyTime",
+                                "RequestedApplyTime",
+                                std::variant<std::string>{applyTimeNewVal});
+                        }
+                    }
+                }
+            });
+    BMCWEB_ROUTE(app, "/redfish/v1/UpdateService/")
+        .privileges({"ConfigureComponents"})
+        .methods(boost::beast::http::verb::post)(
+            [](const crow::Request& req,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                BMCWEB_LOG_DEBUG << "doPost...";
+
+                // Setup callback for when new software detected
+                monitorForSoftwareAvailable(asyncResp, req,
+                                            "/redfish/v1/UpdateService");
+
+                std::string filepath("/tmp/images/" +
+                                     boost::uuids::to_string(
+                                         boost::uuids::random_generator()()));
+                BMCWEB_LOG_DEBUG << "Writing file to " << filepath;
+                std::ofstream out(filepath, std::ofstream::out |
+                                                std::ofstream::binary |
+                                                std::ofstream::trunc);
+                out << req.body;
+                out.close();
+                BMCWEB_LOG_DEBUG << "file upload complete!!";
+            });
+}
+
+inline void requestRoutesSoftwareInventoryCollection(App& app)
+{
+    BMCWEB_ROUTE(app, "/redfish/v1/UpdateService/FirmwareInventory/")
+        .privileges({"Login"})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                asyncResp->res.jsonValue["@odata.type"] =
+                    "#SoftwareInventoryCollection.SoftwareInventoryCollection";
+                asyncResp->res.jsonValue["@odata.id"] =
+                    "/redfish/v1/UpdateService/FirmwareInventory";
+                asyncResp->res.jsonValue["Name"] =
+                    "Software Inventory Collection";
+
+                crow::connections::systemBus->async_method_call(
+                    [asyncResp](
+                        const boost::system::error_code ec,
+                        const std::vector<std::pair<
+                            std::string,
+                            std::vector<std::pair<std::string,
+                                                  std::vector<std::string>>>>>&
+                            subtree) {
+                        if (ec)
+                        {
+                            messages::internalError(asyncResp->res);
+                            return;
+                        }
+                        asyncResp->res.jsonValue["Members"] =
+                            nlohmann::json::array();
+                        asyncResp->res.jsonValue["Members@odata.count"] = 0;
+
+                        for (auto& obj : subtree)
+                        {
+                            sdbusplus::message::object_path path(obj.first);
+                            std::string swId = path.filename();
+                            if (swId.empty())
+                            {
+                                messages::internalError(asyncResp->res);
+                                BMCWEB_LOG_DEBUG << "Can't parse firmware ID!!";
+                                return;
+                            }
+
+                            nlohmann::json& members =
+                                asyncResp->res.jsonValue["Members"];
+                            members.push_back(
+                                {{"@odata.id", "/redfish/v1/UpdateService/"
+                                               "FirmwareInventory/" +
+                                                   swId}});
+                            asyncResp->res.jsonValue["Members@odata.count"] =
+                                members.size();
+                        }
+                    },
+                    // Note that only firmware levels associated with a device
+                    // are stored under /xyz/openbmc_project/software therefore
+                    // to ensure only real FirmwareInventory items are returned,
+                    // this full object path must be used here as input to
+                    // mapper
+                    "xyz.openbmc_project.ObjectMapper",
+                    "/xyz/openbmc_project/object_mapper",
+                    "xyz.openbmc_project.ObjectMapper", "GetSubTree",
+                    "/xyz/openbmc_project/software", static_cast<int32_t>(0),
+                    std::array<const char*, 1>{
+                        "xyz.openbmc_project.Software.Version"});
+            });
+}
+/* Fill related item links (i.e. bmc, bios) in for inventory */
+inline static void
+    getRelatedItems(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
+                    const std::string& purpose)
+{
+    if (purpose == fw_util::bmcPurpose)
+    {
+        nlohmann::json& relatedItem = aResp->res.jsonValue["RelatedItem"];
+        relatedItem.push_back({{"@odata.id", "/redfish/v1/Managers/bmc"}});
+        aResp->res.jsonValue["RelatedItem@odata.count"] = relatedItem.size();
+    }
+    else if (purpose == fw_util::biosPurpose)
+    {
+        nlohmann::json& relatedItem = aResp->res.jsonValue["RelatedItem"];
+        relatedItem.push_back(
+            {{"@odata.id", "/redfish/v1/Systems/system/Bios"}});
+        aResp->res.jsonValue["Members@odata.count"] = relatedItem.size();
+    }
+    else
+    {
+        BMCWEB_LOG_ERROR << "Unknown software purpose " << purpose;
+    }
+}
+
+inline void requestRoutesSoftwareInventory(App& app)
+{
+    BMCWEB_ROUTE(app, "/redfish/v1/UpdateService/FirmwareInventory/<str>/")
+        .privileges({"Login"})
+        .methods(
+            boost::beast::http::verb::get)([](const crow::Request&,
+                                              const std::shared_ptr<
+                                                  bmcweb::AsyncResp>& asyncResp,
+                                              const std::string& param) {
+            std::shared_ptr<std::string> swId =
+                std::make_shared<std::string>(param);
+
+            asyncResp->res.jsonValue["@odata.id"] =
+                "/redfish/v1/UpdateService/FirmwareInventory/" + *swId;
+
+            crow::connections::systemBus->async_method_call(
+                [asyncResp, swId](
+                    const boost::system::error_code ec,
+                    const std::vector<
+                        std::pair<std::string,
+                                  std::vector<std::pair<
+                                      std::string, std::vector<std::string>>>>>&
+                        subtree) {
+                    BMCWEB_LOG_DEBUG << "doGet callback...";
+                    if (ec)
                     {
                         messages::internalError(asyncResp->res);
-                        BMCWEB_LOG_DEBUG << "Can't parse firmware ID!!";
                         return;
                     }
 
-                    nlohmann::json& members =
-                        asyncResp->res.jsonValue["Members"];
-                    members.push_back(
-                        {{"@odata.id", "/redfish/v1/UpdateService/"
-                                       "FirmwareInventory/" +
-                                           swId}});
-                    asyncResp->res.jsonValue["Members@odata.count"] =
-                        members.size();
-                }
-            },
-            // Note that only firmware levels associated with a device are
-            // stored under /xyz/openbmc_project/software therefore to ensure
-            // only real FirmwareInventory items are returned, this full object
-            // path must be used here as input to mapper
-            "xyz.openbmc_project.ObjectMapper",
-            "/xyz/openbmc_project/object_mapper",
-            "xyz.openbmc_project.ObjectMapper", "GetSubTree",
-            "/xyz/openbmc_project/software", static_cast<int32_t>(0),
-            std::array<const char*, 1>{"xyz.openbmc_project.Software.Version"});
-    }
-};
-
-class SoftwareInventory : public Node
-{
-  public:
-    SoftwareInventory(App& app) :
-        Node(app, "/redfish/v1/UpdateService/FirmwareInventory/<str>/",
-             std::string())
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
-    }
-
-  private:
-    /* Fill related item links (i.e. bmc, bios) in for inventory */
-    static void getRelatedItems(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
-                                const std::string& purpose)
-    {
-        if (purpose == fw_util::bmcPurpose)
-        {
-            nlohmann::json& relatedItem = aResp->res.jsonValue["RelatedItem"];
-            relatedItem.push_back({{"@odata.id", "/redfish/v1/Managers/bmc"}});
-            aResp->res.jsonValue["RelatedItem@odata.count"] =
-                relatedItem.size();
-        }
-        else if (purpose == fw_util::biosPurpose)
-        {
-            nlohmann::json& relatedItem = aResp->res.jsonValue["RelatedItem"];
-            relatedItem.push_back(
-                {{"@odata.id", "/redfish/v1/Systems/system/Bios"}});
-            aResp->res.jsonValue["RelatedItem@odata.count"] =
-                relatedItem.size();
-        }
-        else
-        {
-            BMCWEB_LOG_ERROR << "Unknown software purpose " << purpose;
-        }
-    }
-
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&,
-               const std::vector<std::string>& params) override
-    {
-        if (params.size() != 1)
-        {
-            messages::internalError(asyncResp->res);
-
-            return;
-        }
-
-        std::shared_ptr<std::string> swId =
-            std::make_shared<std::string>(params[0]);
-
-        asyncResp->res.jsonValue["@odata.id"] =
-            "/redfish/v1/UpdateService/FirmwareInventory/" + *swId;
-
-        crow::connections::systemBus->async_method_call(
-            [asyncResp, swId](
-                const boost::system::error_code ec,
-                const std::vector<std::pair<
-                    std::string, std::vector<std::pair<
-                                     std::string, std::vector<std::string>>>>>&
-                    subtree) {
-                BMCWEB_LOG_DEBUG << "doGet callback...";
-                if (ec)
-                {
-                    messages::internalError(asyncResp->res);
-                    return;
-                }
-
-                // Ensure we find our input swId, otherwise return an error
-                bool found = false;
-                for (const std::pair<
-                         std::string,
-                         std::vector<
-                             std::pair<std::string, std::vector<std::string>>>>&
-                         obj : subtree)
-                {
-                    if (boost::ends_with(obj.first, *swId) != true)
+                    // Ensure we find our input swId, otherwise return an error
+                    bool found = false;
+                    for (const std::pair<
+                             std::string,
+                             std::vector<std::pair<
+                                 std::string, std::vector<std::string>>>>& obj :
+                         subtree)
                     {
-                        continue;
-                    }
+                        if (boost::ends_with(obj.first, *swId) != true)
+                        {
+                            continue;
+                        }
 
-                    if (obj.second.size() < 1)
+                        if (obj.second.size() < 1)
+                        {
+                            continue;
+                        }
+
+                        found = true;
+                        fw_util::getFwStatus(asyncResp, swId,
+                                             obj.second[0].first);
+
+                        crow::connections::systemBus->async_method_call(
+                            [asyncResp, swId](
+                                const boost::system::error_code errorCode,
+                                const boost::container::flat_map<
+                                    std::string, VariantType>& propertiesList) {
+                                if (errorCode)
+                                {
+                                    messages::internalError(asyncResp->res);
+                                    return;
+                                }
+                                boost::container::flat_map<
+                                    std::string, VariantType>::const_iterator
+                                    it = propertiesList.find("Purpose");
+                                if (it == propertiesList.end())
+                                {
+                                    BMCWEB_LOG_DEBUG
+                                        << "Can't find property \"Purpose\"!";
+                                    messages::propertyMissing(asyncResp->res,
+                                                              "Purpose");
+                                    return;
+                                }
+                                const std::string* swInvPurpose =
+                                    std::get_if<std::string>(&it->second);
+                                if (swInvPurpose == nullptr)
+                                {
+                                    BMCWEB_LOG_DEBUG << "wrong types for "
+                                                        "property\"Purpose\"!";
+                                    messages::propertyValueTypeError(
+                                        asyncResp->res, "", "Purpose");
+                                    return;
+                                }
+
+                                BMCWEB_LOG_DEBUG << "swInvPurpose = "
+                                                 << *swInvPurpose;
+                                it = propertiesList.find("Version");
+                                if (it == propertiesList.end())
+                                {
+                                    BMCWEB_LOG_DEBUG
+                                        << "Can't find property \"Version\"!";
+                                    messages::propertyMissing(asyncResp->res,
+                                                              "Version");
+                                    return;
+                                }
+
+                                BMCWEB_LOG_DEBUG << "Version found!";
+
+                                const std::string* version =
+                                    std::get_if<std::string>(&it->second);
+
+                                if (version == nullptr)
+                                {
+                                    BMCWEB_LOG_DEBUG
+                                        << "Can't find property \"Version\"!";
+
+                                    messages::propertyValueTypeError(
+                                        asyncResp->res, "", "Version");
+                                    return;
+                                }
+                                asyncResp->res.jsonValue["Version"] = *version;
+                                asyncResp->res.jsonValue["Id"] = *swId;
+
+                                // swInvPurpose is of format:
+                                // xyz.openbmc_project.Software.Version.VersionPurpose.ABC
+                                // Translate this to "ABC image"
+                                size_t endDesc = swInvPurpose->rfind('.');
+                                if (endDesc == std::string::npos)
+                                {
+                                    messages::internalError(asyncResp->res);
+                                    return;
+                                }
+                                endDesc++;
+                                if (endDesc >= swInvPurpose->size())
+                                {
+                                    messages::internalError(asyncResp->res);
+                                    return;
+                                }
+
+                                std::string formatDesc =
+                                    swInvPurpose->substr(endDesc);
+                                asyncResp->res.jsonValue["Description"] =
+                                    formatDesc + " image";
+                                getRelatedItems(asyncResp, *swInvPurpose);
+                            },
+                            obj.second[0].first, obj.first,
+                            "org.freedesktop.DBus.Properties", "GetAll",
+                            "xyz.openbmc_project.Software.Version");
+                    }
+                    if (!found)
                     {
-                        continue;
+                        BMCWEB_LOG_ERROR
+                            << "Input swID " + *swId + " not found!";
+                        messages::resourceMissingAtURI(
+                            asyncResp->res,
+                            "/redfish/v1/UpdateService/FirmwareInventory/" +
+                                *swId);
+                        return;
                     }
+                    asyncResp->res.jsonValue["@odata.type"] =
+                        "#SoftwareInventory.v1_1_0.SoftwareInventory";
+                    asyncResp->res.jsonValue["Name"] = "Software Inventory";
+                    asyncResp->res.jsonValue["Status"]["HealthRollup"] = "OK";
 
-                    found = true;
-                    fw_util::getFwStatus(asyncResp, swId, obj.second[0].first);
-
-                    crow::connections::systemBus->async_method_call(
-                        [asyncResp,
-                         swId](const boost::system::error_code errorCode,
-                               const boost::container::flat_map<
-                                   std::string, VariantType>& propertiesList) {
-                            if (errorCode)
-                            {
-                                messages::internalError(asyncResp->res);
-                                return;
-                            }
-                            boost::container::flat_map<
-                                std::string, VariantType>::const_iterator it =
-                                propertiesList.find("Purpose");
-                            if (it == propertiesList.end())
-                            {
-                                BMCWEB_LOG_DEBUG
-                                    << "Can't find property \"Purpose\"!";
-                                messages::propertyMissing(asyncResp->res,
-                                                          "Purpose");
-                                return;
-                            }
-                            const std::string* swInvPurpose =
-                                std::get_if<std::string>(&it->second);
-                            if (swInvPurpose == nullptr)
-                            {
-                                BMCWEB_LOG_DEBUG
-                                    << "wrong types for property\"Purpose\"!";
-                                messages::propertyValueTypeError(asyncResp->res,
-                                                                 "", "Purpose");
-                                return;
-                            }
-
-                            BMCWEB_LOG_DEBUG << "swInvPurpose = "
-                                             << *swInvPurpose;
-                            it = propertiesList.find("Version");
-                            if (it == propertiesList.end())
-                            {
-                                BMCWEB_LOG_DEBUG
-                                    << "Can't find property \"Version\"!";
-                                messages::propertyMissing(asyncResp->res,
-                                                          "Version");
-                                return;
-                            }
-
-                            BMCWEB_LOG_DEBUG << "Version found!";
-
-                            const std::string* version =
-                                std::get_if<std::string>(&it->second);
-
-                            if (version == nullptr)
-                            {
-                                BMCWEB_LOG_DEBUG
-                                    << "Can't find property \"Version\"!";
-
-                                messages::propertyValueTypeError(asyncResp->res,
-                                                                 "", "Version");
-                                return;
-                            }
-                            asyncResp->res.jsonValue["Version"] = *version;
-                            asyncResp->res.jsonValue["Id"] = *swId;
-
-                            // swInvPurpose is of format:
-                            // xyz.openbmc_project.Software.Version.VersionPurpose.ABC
-                            // Translate this to "ABC image"
-                            size_t endDesc = swInvPurpose->rfind('.');
-                            if (endDesc == std::string::npos)
-                            {
-                                messages::internalError(asyncResp->res);
-                                return;
-                            }
-                            endDesc++;
-                            if (endDesc >= swInvPurpose->size())
-                            {
-                                messages::internalError(asyncResp->res);
-                                return;
-                            }
-
-                            std::string formatDesc =
-                                swInvPurpose->substr(endDesc);
-                            asyncResp->res.jsonValue["Description"] =
-                                formatDesc + " image";
-                            getRelatedItems(asyncResp, *swInvPurpose);
-                        },
-                        obj.second[0].first, obj.first,
-                        "org.freedesktop.DBus.Properties", "GetAll",
-                        "xyz.openbmc_project.Software.Version");
-                }
-                if (!found)
-                {
-                    BMCWEB_LOG_ERROR << "Input swID " + *swId + " not found!";
-                    messages::resourceMissingAtURI(
-                        asyncResp->res,
-                        "/redfish/v1/UpdateService/FirmwareInventory/" + *swId);
-                    return;
-                }
-                asyncResp->res.jsonValue["@odata.type"] =
-                    "#SoftwareInventory.v1_1_0.SoftwareInventory";
-                asyncResp->res.jsonValue["Name"] = "Software Inventory";
-                asyncResp->res.jsonValue["Status"]["HealthRollup"] = "OK";
-
-                asyncResp->res.jsonValue["Updateable"] = false;
-                fw_util::getFwUpdateableStatus(asyncResp, swId);
-            },
-            "xyz.openbmc_project.ObjectMapper",
-            "/xyz/openbmc_project/object_mapper",
-            "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/",
-            static_cast<int32_t>(0),
-            std::array<const char*, 1>{"xyz.openbmc_project.Software.Version"});
-    }
-};
+                    asyncResp->res.jsonValue["Updateable"] = false;
+                    fw_util::getFwUpdateableStatus(asyncResp, swId);
+                },
+                "xyz.openbmc_project.ObjectMapper",
+                "/xyz/openbmc_project/object_mapper",
+                "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/",
+                static_cast<int32_t>(0),
+                std::array<const char*, 1>{
+                    "xyz.openbmc_project.Software.Version"});
+        });
+}
 
 } // namespace redfish
diff --git a/redfish-core/lib/virtual_media.hpp b/redfish-core/lib/virtual_media.hpp
index 685ee5c..ce40f67 100644
--- a/redfish-core/lib/virtual_media.hpp
+++ b/redfish-core/lib/virtual_media.hpp
@@ -15,6 +15,7 @@
 */
 #pragma once
 
+#include <app.hpp>
 #include <boost/container/flat_map.hpp>
 #include <boost/process/async_pipe.hpp>
 #include <boost/type_traits/has_dereference.hpp>
