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>
