diff --git a/redfish-core/lib/storage.hpp b/redfish-core/lib/storage.hpp
index 44b7746..53af1f1 100644
--- a/redfish-core/lib/storage.hpp
+++ b/redfish-core/lib/storage.hpp
@@ -39,39 +39,86 @@
 
 namespace redfish
 {
+
+inline void handleSystemsStorageCollectionGet(
+    App& app, const crow::Request& req,
+    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+    const std::string& systemName)
+{
+    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+    {
+        return;
+    }
+    if (systemName != "system")
+    {
+        messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+                                   systemName);
+        return;
+    }
+
+    asyncResp->res.jsonValue["@odata.type"] =
+        "#StorageCollection.StorageCollection";
+    asyncResp->res.jsonValue["@odata.id"] =
+        "/redfish/v1/Systems/system/Storage";
+    asyncResp->res.jsonValue["Name"] = "Storage Collection";
+    nlohmann::json::array_t members;
+    nlohmann::json::object_t member;
+    member["@odata.id"] = "/redfish/v1/Systems/system/Storage/1";
+    members.emplace_back(member);
+    asyncResp->res.jsonValue["Members"] = std::move(members);
+    asyncResp->res.jsonValue["Members@odata.count"] = 1;
+}
+
 inline void requestRoutesStorageCollection(App& app)
 {
     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Storage/")
         .privileges(redfish::privileges::getStorageCollection)
         .methods(boost::beast::http::verb::get)(
-            [&app](const crow::Request& req,
-                   const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                   const std::string& systemName) {
-        if (!redfish::setUpRedfishRoute(app, req, asyncResp))
-        {
-            return;
-        }
-        if (systemName != "system")
-        {
-            messages::resourceNotFound(asyncResp->res, "ComputerSystem",
-                                       systemName);
-            return;
-        }
-
-        asyncResp->res.jsonValue["@odata.type"] =
-            "#StorageCollection.StorageCollection";
-        asyncResp->res.jsonValue["@odata.id"] =
-            "/redfish/v1/Systems/system/Storage";
-        asyncResp->res.jsonValue["Name"] = "Storage Collection";
-        nlohmann::json::array_t members;
-        nlohmann::json::object_t member;
-        member["@odata.id"] = "/redfish/v1/Systems/system/Storage/1";
-        members.emplace_back(member);
-        asyncResp->res.jsonValue["Members"] = std::move(members);
-        asyncResp->res.jsonValue["Members@odata.count"] = 1;
-        });
+            std::bind_front(handleSystemsStorageCollectionGet, std::ref(app)));
 }
 
+inline void afterChassisDriveCollectionSubtree(
+    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+    const std::shared_ptr<HealthPopulate>& health,
+    const boost::system::error_code& ec,
+    const dbus::utility::MapperGetSubTreePathsResponse& driveList)
+{
+    if (ec)
+    {
+        BMCWEB_LOG_ERROR << "Drive mapper call error";
+        messages::internalError(asyncResp->res);
+        return;
+    }
+
+    nlohmann::json& driveArray = asyncResp->res.jsonValue["Drives"];
+    driveArray = nlohmann::json::array();
+    auto& count = asyncResp->res.jsonValue["Drives@odata.count"];
+    count = 0;
+
+    if constexpr (bmcwebEnableHealthPopulate)
+    {
+        health->inventory.insert(health->inventory.end(), driveList.begin(),
+                                 driveList.end());
+    }
+
+    for (const std::string& drive : driveList)
+    {
+        sdbusplus::message::object_path object(drive);
+        if (object.filename().empty())
+        {
+            BMCWEB_LOG_ERROR << "Failed to find filename in " << drive;
+            return;
+        }
+
+        nlohmann::json::object_t driveJson;
+        driveJson["@odata.id"] = boost::urls::format(
+            "/redfish/v1/Systems/system/Storage/1/Drives/{}",
+            object.filename());
+        driveArray.emplace_back(std::move(driveJson));
+    }
+
+    count = driveArray.size();
+}
 inline void getDrives(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                       const std::shared_ptr<HealthPopulate>& health)
 {
@@ -79,45 +126,33 @@
         "xyz.openbmc_project.Inventory.Item.Drive"};
     dbus::utility::getSubTreePaths(
         "/xyz/openbmc_project/inventory", 0, interfaces,
-        [asyncResp, health](
-            const boost::system::error_code& ec,
-            const dbus::utility::MapperGetSubTreePathsResponse& driveList) {
-        if (ec)
-        {
-            BMCWEB_LOG_ERROR << "Drive mapper call error";
-            messages::internalError(asyncResp->res);
-            return;
-        }
+        std::bind_front(afterChassisDriveCollectionSubtree, asyncResp, health));
+}
 
-        nlohmann::json& driveArray = asyncResp->res.jsonValue["Drives"];
-        driveArray = nlohmann::json::array();
-        auto& count = asyncResp->res.jsonValue["Drives@odata.count"];
-        count = 0;
+inline void
+    handleSystemsStorageGet(App& app, const crow::Request& req,
+                            const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+{
+    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+    {
+        return;
+    }
+    asyncResp->res.jsonValue["@odata.type"] = "#Storage.v1_13_0.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";
 
-        if constexpr (bmcwebEnableHealthPopulate)
-        {
-            health->inventory.insert(health->inventory.end(), driveList.begin(),
-                                     driveList.end());
-        }
+    auto health = std::make_shared<HealthPopulate>(asyncResp);
+    if constexpr (bmcwebEnableHealthPopulate)
+    {
+        health->populate();
+    }
 
-        for (const std::string& drive : driveList)
-        {
-            sdbusplus::message::object_path object(drive);
-            if (object.filename().empty())
-            {
-                BMCWEB_LOG_ERROR << "Failed to find filename in " << drive;
-                return;
-            }
-
-            nlohmann::json::object_t driveJson;
-            driveJson["@odata.id"] = boost::urls::format(
-                "/redfish/v1/Systems/system/Storage/1/Drives/{}",
-                object.filename());
-            driveArray.emplace_back(std::move(driveJson));
-        }
-
-        count = driveArray.size();
-        });
+    getDrives(asyncResp, health);
+    asyncResp->res.jsonValue["Controllers"]["@odata.id"] =
+        "/redfish/v1/Systems/system/Storage/1/Controllers";
 }
 
 inline void requestRoutesStorage(App& app)
@@ -125,29 +160,7 @@
     BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/Storage/1/")
         .privileges(redfish::privileges::getStorage)
         .methods(boost::beast::http::verb::get)(
-            [&app](const crow::Request& req,
-                   const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
-        if (!redfish::setUpRedfishRoute(app, req, asyncResp))
-        {
-            return;
-        }
-        asyncResp->res.jsonValue["@odata.type"] = "#Storage.v1_13_0.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);
-        if constexpr (bmcwebEnableHealthPopulate)
-        {
-            health->populate();
-        }
-
-        getDrives(asyncResp, health);
-        asyncResp->res.jsonValue["Controllers"]["@odata.id"] =
-            "/redfish/v1/Systems/system/Storage/1/Controllers";
-        });
+            std::bind_front(handleSystemsStorageGet, std::ref(app)));
 }
 
 inline void getDriveAsset(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
@@ -491,96 +504,175 @@
     }
 }
 
+inline void afterGetSubtreeSystemsStorageDrive(
+    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+    const std::string& driveId, const boost::system::error_code& ec,
+    const dbus::utility::MapperGetSubTreeResponse& subtree)
+{
+    if (ec)
+    {
+        BMCWEB_LOG_ERROR << "Drive mapper call error";
+        messages::internalError(asyncResp->res);
+        return;
+    }
+
+    auto drive = std::find_if(
+        subtree.begin(), subtree.end(),
+        [&driveId](const std::pair<std::string,
+                                   dbus::utility::MapperServiceMap>& object) {
+        return sdbusplus::message::object_path(object.first).filename() ==
+               driveId;
+        });
+
+    if (drive == subtree.end())
+    {
+        messages::resourceNotFound(asyncResp->res, "Drive", driveId);
+        return;
+    }
+
+    const std::string& path = drive->first;
+    const dbus::utility::MapperServiceMap& connectionNames = drive->second;
+
+    asyncResp->res.jsonValue["@odata.type"] = "#Drive.v1_7_0.Drive";
+    asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
+        "/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()
+                         << ", not equal to 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"] =
+            boost::urls::format("/redfish/v1/Chassis/{}", chassisId);
+    });
+
+    // default it to Enabled
+    asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
+
+    if constexpr (bmcwebEnableHealthPopulate)
+    {
+        auto health = std::make_shared<HealthPopulate>(asyncResp);
+        health->inventory.emplace_back(path);
+        health->populate();
+    }
+
+    addAllDriveInfo(asyncResp, connectionNames[0].first, path,
+                    connectionNames[0].second);
+}
+
+inline void handleSystemsStorageDriveGet(
+    App& app, const crow::Request& req,
+    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+    const std::string& systemName, const std::string& driveId)
+{
+    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+    {
+        return;
+    }
+    if (systemName != "system")
+    {
+        messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+                                   systemName);
+        return;
+    }
+
+    constexpr std::array<std::string_view, 1> interfaces = {
+        "xyz.openbmc_project.Inventory.Item.Drive"};
+    dbus::utility::getSubTree(
+        "/xyz/openbmc_project/inventory", 0, interfaces,
+        std::bind_front(afterGetSubtreeSystemsStorageDrive, asyncResp,
+                        driveId));
+}
+
 inline void requestRoutesDrive(App& app)
 {
     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Storage/1/Drives/<str>/")
         .privileges(redfish::privileges::getDrive)
         .methods(boost::beast::http::verb::get)(
-            [&app](const crow::Request& req,
-                   const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                   const std::string& systemName, const std::string& driveId) {
-        if (!redfish::setUpRedfishRoute(app, req, asyncResp))
-        {
-            return;
-        }
-        if (systemName != "system")
-        {
-            messages::resourceNotFound(asyncResp->res, "ComputerSystem",
-                                       systemName);
-            return;
-        }
-
-        constexpr std::array<std::string_view, 1> interfaces = {
-            "xyz.openbmc_project.Inventory.Item.Drive"};
-        dbus::utility::getSubTree(
-            "/xyz/openbmc_project/inventory", 0, interfaces,
-            [asyncResp,
-             driveId](const boost::system::error_code& ec,
-                      const dbus::utility::MapperGetSubTreeResponse& subtree) {
-            if (ec)
-            {
-                BMCWEB_LOG_ERROR << "Drive mapper call error";
-                messages::internalError(asyncResp->res);
-                return;
-            }
-
-            auto drive = std::find_if(
-                subtree.begin(), subtree.end(),
-                [&driveId](
-                    const std::pair<std::string,
-                                    dbus::utility::MapperServiceMap>& object) {
-                return sdbusplus::message::object_path(object.first)
-                           .filename() == driveId;
-                });
-
-            if (drive == subtree.end())
-            {
-                messages::resourceNotFound(asyncResp->res, "Drive", driveId);
-                return;
-            }
-
-            const std::string& path = drive->first;
-            const dbus::utility::MapperServiceMap& connectionNames =
-                drive->second;
-
-            asyncResp->res.jsonValue["@odata.type"] = "#Drive.v1_7_0.Drive";
-            asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
-                "/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()
-                                 << ", not equal to 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"] =
-                    boost::urls::format("/redfish/v1/Chassis/{}", chassisId);
-                });
-
-            // default it to Enabled
-            asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
-
-            if constexpr (bmcwebEnableHealthPopulate)
-            {
-                auto health = std::make_shared<HealthPopulate>(asyncResp);
-                health->inventory.emplace_back(path);
-                health->populate();
-            }
-
-            addAllDriveInfo(asyncResp, connectionNames[0].first, path,
-                            connectionNames[0].second);
-            });
-        });
+            std::bind_front(handleSystemsStorageDriveGet, std::ref(app)));
 }
 
+inline void afterChassisDriveCollectionSubtreeGet(
+    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+    const std::string& chassisId, const boost::system::error_code& ec,
+    const dbus::utility::MapperGetSubTreeResponse& subtree)
+{
+    if (ec)
+    {
+        if (ec == boost::system::errc::host_unreachable)
+        {
+            messages::resourceNotFound(asyncResp->res, "Chassis", chassisId);
+            return;
+        }
+        messages::internalError(asyncResp->res);
+        return;
+    }
+
+    // Iterate over all retrieved ObjectPaths.
+    for (const auto& [path, connectionNames] : subtree)
+    {
+        sdbusplus::message::object_path objPath(path);
+        if (objPath.filename() != chassisId)
+        {
+            continue;
+        }
+
+        if (connectionNames.empty())
+        {
+            BMCWEB_LOG_ERROR << "Got 0 Connection names";
+            continue;
+        }
+
+        asyncResp->res.jsonValue["@odata.type"] =
+            "#DriveCollection.DriveCollection";
+        asyncResp->res.jsonValue["@odata.id"] =
+            boost::urls::format("/redfish/v1/Chassis/{}/Drives", chassisId);
+        asyncResp->res.jsonValue["Name"] = "Drive Collection";
+
+        // Association lambda
+        dbus::utility::getAssociationEndPoints(
+            path + "/drive",
+            [asyncResp, chassisId](const boost::system::error_code& ec3,
+                                   const dbus::utility::MapperEndPoints& resp) {
+            if (ec3)
+            {
+                BMCWEB_LOG_ERROR << "Error in chassis Drive association ";
+            }
+            nlohmann::json& members = asyncResp->res.jsonValue["Members"];
+            // important if array is empty
+            members = nlohmann::json::array();
+
+            std::vector<std::string> leafNames;
+            for (const auto& drive : resp)
+            {
+                sdbusplus::message::object_path drivePath(drive);
+                leafNames.push_back(drivePath.filename());
+            }
+
+            std::sort(leafNames.begin(), leafNames.end(),
+                      AlphanumLess<std::string>());
+
+            for (const auto& leafName : leafNames)
+            {
+                nlohmann::json::object_t member;
+                member["@odata.id"] = boost::urls::format(
+                    "/redfish/v1/Chassis/{}/Drives/{}", chassisId, leafName);
+                members.emplace_back(std::move(member));
+                // navigation links will be registered in next patch set
+            }
+            asyncResp->res.jsonValue["Members@odata.count"] = resp.size();
+            }); // end association lambda
+
+    }           // end Iterate over all retrieved ObjectPaths
+}
 /**
  * Chassis drives, this URL will show all the DriveCollection
  * information
@@ -601,80 +693,8 @@
         "xyz.openbmc_project.Inventory.Item.Chassis"};
     dbus::utility::getSubTree(
         "/xyz/openbmc_project/inventory", 0, interfaces,
-        [asyncResp,
-         chassisId](const boost::system::error_code& ec,
-                    const dbus::utility::MapperGetSubTreeResponse& subtree) {
-        if (ec)
-        {
-            if (ec == boost::system::errc::host_unreachable)
-            {
-                messages::resourceNotFound(asyncResp->res, "Chassis",
-                                           chassisId);
-                return;
-            }
-            messages::internalError(asyncResp->res);
-            return;
-        }
-
-        // Iterate over all retrieved ObjectPaths.
-        for (const auto& [path, connectionNames] : subtree)
-        {
-            sdbusplus::message::object_path objPath(path);
-            if (objPath.filename() != chassisId)
-            {
-                continue;
-            }
-
-            if (connectionNames.empty())
-            {
-                BMCWEB_LOG_ERROR << "Got 0 Connection names";
-                continue;
-            }
-
-            asyncResp->res.jsonValue["@odata.type"] =
-                "#DriveCollection.DriveCollection";
-            asyncResp->res.jsonValue["@odata.id"] =
-                boost::urls::format("/redfish/v1/Chassis/{}/Drives", chassisId);
-            asyncResp->res.jsonValue["Name"] = "Drive Collection";
-
-            // Association lambda
-            dbus::utility::getAssociationEndPoints(
-                path + "/drive",
-                [asyncResp,
-                 chassisId](const boost::system::error_code& ec3,
-                            const dbus::utility::MapperEndPoints& resp) {
-                if (ec3)
-                {
-                    BMCWEB_LOG_ERROR << "Error in chassis Drive association ";
-                }
-                nlohmann::json& members = asyncResp->res.jsonValue["Members"];
-                // important if array is empty
-                members = nlohmann::json::array();
-
-                std::vector<std::string> leafNames;
-                for (const auto& drive : resp)
-                {
-                    sdbusplus::message::object_path drivePath(drive);
-                    leafNames.push_back(drivePath.filename());
-                }
-
-                std::sort(leafNames.begin(), leafNames.end(),
-                          AlphanumLess<std::string>());
-
-                for (const auto& leafName : leafNames)
-                {
-                    nlohmann::json::object_t member;
-                    member["@odata.id"] =
-                        boost::urls::format("/redfish/v1/Chassis/{}/Drives/{}",
-                                            chassisId, leafName);
-                    members.emplace_back(std::move(member));
-                    // navigation links will be registered in next patch set
-                }
-                asyncResp->res.jsonValue["Members@odata.count"] = resp.size();
-                }); // end association lambda
-
-        }           // end Iterate over all retrieved ObjectPaths
-        });
+        std::bind_front(afterChassisDriveCollectionSubtreeGet, asyncResp,
+                        chassisId));
 }
 
 inline void requestRoutesChassisDrive(App& app)
@@ -986,7 +1006,7 @@
     asyncResp->res.jsonValue["Members"] = std::move(members);
 }
 
-inline void storageControllerCollectionHandler(
+inline void handleSystemsStorageControllerCollectionGet(
     App& app, const crow::Request& req,
     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
     const std::string& systemName)
@@ -1022,7 +1042,7 @@
         });
 }
 
-inline void storageControllerHandler(
+inline void handleSystemsStorageControllerGet(
     App& app, const crow::Request& req,
     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
     const std::string& systemName, const std::string& controllerId)
@@ -1055,8 +1075,8 @@
 {
     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Storage/1/Controllers/")
         .privileges(redfish::privileges::getStorageControllerCollection)
-        .methods(boost::beast::http::verb::get)(
-            std::bind_front(storageControllerCollectionHandler, std::ref(app)));
+        .methods(boost::beast::http::verb::get)(std::bind_front(
+            handleSystemsStorageControllerCollectionGet, std::ref(app)));
 }
 
 inline void requestRoutesStorageController(App& app)
@@ -1064,7 +1084,7 @@
     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Storage/1/Controllers/<str>")
         .privileges(redfish::privileges::getStorageController)
         .methods(boost::beast::http::verb::get)(
-            std::bind_front(storageControllerHandler, std::ref(app)));
+            std::bind_front(handleSystemsStorageControllerGet, std::ref(app)));
 }
 
 } // namespace redfish
