diff --git a/redfish-core/lib/redfish_sessions.hpp b/redfish-core/lib/redfish_sessions.hpp
index a66f460..5e7d3df 100644
--- a/redfish-core/lib/redfish_sessions.hpp
+++ b/redfish-core/lib/redfish_sessions.hpp
@@ -25,8 +25,6 @@
 namespace redfish
 {
 
-class SessionCollection;
-
 inline void fillSessionObject(crow::Response& res,
                               const persistent_data::UserSession& session)
 {
@@ -45,240 +43,252 @@
 #endif
 }
 
+inline void
+    handleSessionGet(const crow::Request& /*req*/,
+                     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+                     const std::string& sessionId)
+{
+    // Note that control also reaches here via doPost and doDelete.
+    auto session =
+        persistent_data::SessionStore::getInstance().getSessionByUid(sessionId);
+
+    if (session == nullptr)
+    {
+        messages::resourceNotFound(asyncResp->res, "Session", sessionId);
+        return;
+    }
+
+    fillSessionObject(asyncResp->res, *session);
+}
+
+inline void
+    handleSessionDelete(const crow::Request& req,
+                        const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+                        const std::string& sessionId)
+{
+    auto session =
+        persistent_data::SessionStore::getInstance().getSessionByUid(sessionId);
+
+    if (session == nullptr)
+    {
+        messages::resourceNotFound(asyncResp->res, "Session", sessionId);
+        return;
+    }
+
+    // Perform a proper ConfigureSelf authority check.  If a
+    // session is being used to DELETE some other user's session,
+    // then the ConfigureSelf privilege does not apply.  In that
+    // case, perform the authority check again without the user's
+    // ConfigureSelf privilege.
+    if (session->username != req.session->username)
+    {
+        Privileges effectiveUserPrivileges =
+            redfish::getUserPrivileges(req.userRole);
+
+        if (!effectiveUserPrivileges.isSupersetOf({"ConfigureUsers"}))
+        {
+            messages::insufficientPrivilege(asyncResp->res);
+            return;
+        }
+    }
+
+    persistent_data::SessionStore::getInstance().removeSession(session);
+    messages::success(asyncResp->res);
+}
+
+inline nlohmann::json getSessionCollectionMembers()
+{
+    std::vector<const std::string*> sessionIds =
+        persistent_data::SessionStore::getInstance().getUniqueIds(
+            false, persistent_data::PersistenceType::TIMEOUT);
+    nlohmann::json ret = nlohmann::json::array();
+    for (const std::string* uid : sessionIds)
+    {
+        ret.push_back(
+            {{"@odata.id", "/redfish/v1/SessionService/Sessions/" + *uid}});
+    }
+    return ret;
+}
+
+inline void handleSessionCollectionGet(
+    const crow::Request& /*req*/,
+    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+{
+    asyncResp->res.jsonValue["Members"] = getSessionCollectionMembers();
+    asyncResp->res.jsonValue["Members@odata.count"] =
+        asyncResp->res.jsonValue["Members"].size();
+    asyncResp->res.jsonValue["@odata.type"] =
+        "#SessionCollection.SessionCollection";
+    asyncResp->res.jsonValue["@odata.id"] =
+        "/redfish/v1/SessionService/Sessions/";
+    asyncResp->res.jsonValue["Name"] = "Session Collection";
+    asyncResp->res.jsonValue["Description"] = "Session Collection";
+}
+
+inline void handleSessionCollectionMembersGet(
+    const crow::Request& /*req*/,
+    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+{
+    asyncResp->res.jsonValue = getSessionCollectionMembers();
+}
+
+void handleSessionCollectionPost(
+    const crow::Request& req,
+    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+{
+    std::string username;
+    std::string password;
+    std::optional<nlohmann::json> oemObject;
+    std::string clientId;
+    if (!json_util::readJsonPatch(req, asyncResp->res, "UserName", username,
+                                  "Password", password, "Oem", oemObject))
+    {
+        return;
+    }
+
+    if (password.empty() || username.empty() ||
+        asyncResp->res.result() != boost::beast::http::status::ok)
+    {
+        if (username.empty())
+        {
+            messages::propertyMissing(asyncResp->res, "UserName");
+        }
+
+        if (password.empty())
+        {
+            messages::propertyMissing(asyncResp->res, "Password");
+        }
+
+        return;
+    }
+
+    int pamrc = pamAuthenticateUser(username, password);
+    bool isConfigureSelfOnly = pamrc == PAM_NEW_AUTHTOK_REQD;
+    if ((pamrc != PAM_SUCCESS) && !isConfigureSelfOnly)
+    {
+        messages::resourceAtUriUnauthorized(asyncResp->res, req.urlView,
+                                            "Invalid username or password");
+        return;
+    }
+#ifdef BMCWEB_ENABLE_IBM_MANAGEMENT_CONSOLE
+    if (oemObject)
+    {
+        std::optional<nlohmann::json> bmcOem;
+        if (!json_util::readJson(*oemObject, asyncResp->res, "OpenBMC", bmcOem))
+        {
+            return;
+        }
+        if (!json_util::readJson(*bmcOem, asyncResp->res, "ClientID", clientId))
+        {
+            BMCWEB_LOG_ERROR << "Could not read ClientId";
+            return;
+        }
+    }
+#endif
+
+    // User is authenticated - create session
+    std::shared_ptr<persistent_data::UserSession> session =
+        persistent_data::SessionStore::getInstance().generateUserSession(
+            username, req.ipAddress, clientId,
+            persistent_data::PersistenceType::TIMEOUT, isConfigureSelfOnly);
+    asyncResp->res.addHeader("X-Auth-Token", session->sessionToken);
+    asyncResp->res.addHeader(
+        "Location", "/redfish/v1/SessionService/Sessions/" + session->uniqueId);
+    asyncResp->res.result(boost::beast::http::status::created);
+    if (session->isConfigureSelfOnly)
+    {
+        messages::passwordChangeRequired(
+            asyncResp->res,
+            crow::utility::urlFromPieces("redfish", "v1", "AccountService",
+                                         "Accounts", req.session->username));
+    }
+
+    fillSessionObject(asyncResp->res, *session);
+}
+inline void
+    handleSessionServiceGet(const crow::Request& /* req */,
+                            const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+
+{
+    asyncResp->res.jsonValue["@odata.type"] =
+        "#SessionService.v1_0_2.SessionService";
+    asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/SessionService/";
+    asyncResp->res.jsonValue["Name"] = "Session Service";
+    asyncResp->res.jsonValue["Id"] = "SessionService";
+    asyncResp->res.jsonValue["Description"] = "Session Service";
+    asyncResp->res.jsonValue["SessionTimeout"] =
+        persistent_data::SessionStore::getInstance().getTimeoutInSeconds();
+    asyncResp->res.jsonValue["ServiceEnabled"] = true;
+
+    asyncResp->res.jsonValue["Sessions"] = {
+        {"@odata.id", "/redfish/v1/SessionService/Sessions"}};
+}
+
+inline void handleSessionServicePatch(
+    const crow::Request& req,
+    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+{
+    std::optional<int64_t> sessionTimeout;
+    if (!json_util::readJsonPatch(req, asyncResp->res, "SessionTimeout",
+                                  sessionTimeout))
+    {
+        return;
+    }
+
+    if (sessionTimeout)
+    {
+        // The mininum & maximum allowed values for session timeout
+        // are 30 seconds and 86400 seconds respectively as per the
+        // session service schema mentioned at
+        // https://redfish.dmtf.org/schemas/v1/SessionService.v1_1_7.json
+
+        if (*sessionTimeout <= 86400 && *sessionTimeout >= 30)
+        {
+            std::chrono::seconds sessionTimeoutInseconds(*sessionTimeout);
+            persistent_data::SessionStore::getInstance().updateSessionTimeout(
+                sessionTimeoutInseconds);
+            messages::propertyValueModified(asyncResp->res, "SessionTimeOut",
+                                            std::to_string(*sessionTimeout));
+        }
+        else
+        {
+            messages::propertyValueNotInList(asyncResp->res,
+                                             std::to_string(*sessionTimeout),
+                                             "SessionTimeOut");
+        }
+    }
+}
+
 inline void requestRoutesSession(App& app)
 {
     BMCWEB_ROUTE(app, "/redfish/v1/SessionService/Sessions/<str>/")
         .privileges(redfish::privileges::getSession)
-        .methods(boost::beast::http::verb::get)(
-            [](const crow::Request& /*req*/,
-               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const std::string& sessionId) -> void {
-                // Note that control also reaches here via doPost and doDelete.
-                auto session = persistent_data::SessionStore::getInstance()
-                                   .getSessionByUid(sessionId);
-
-                if (session == nullptr)
-                {
-                    messages::resourceNotFound(asyncResp->res, "Session",
-                                               sessionId);
-                    return;
-                }
-
-                fillSessionObject(asyncResp->res, *session);
-            });
+        .methods(boost::beast::http::verb::get)(handleSessionGet);
 
     BMCWEB_ROUTE(app, "/redfish/v1/SessionService/Sessions/<str>/")
         .privileges(redfish::privileges::deleteSession)
-        .methods(boost::beast::http::verb::delete_)(
-            [](const crow::Request& req,
-               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const std::string& sessionId) -> void {
-                auto session = persistent_data::SessionStore::getInstance()
-                                   .getSessionByUid(sessionId);
-
-                if (session == nullptr)
-                {
-                    messages::resourceNotFound(asyncResp->res, "Session",
-                                               sessionId);
-                    return;
-                }
-
-                // Perform a proper ConfigureSelf authority check.  If a
-                // session is being used to DELETE some other user's session,
-                // then the ConfigureSelf privilege does not apply.  In that
-                // case, perform the authority check again without the user's
-                // ConfigureSelf privilege.
-                if (session->username != req.session->username)
-                {
-                    Privileges effectiveUserPrivileges =
-                        redfish::getUserPrivileges(req.userRole);
-
-                    if (!effectiveUserPrivileges.isSupersetOf(
-                            {"ConfigureUsers"}))
-                    {
-                        messages::insufficientPrivilege(asyncResp->res);
-                        return;
-                    }
-                }
-
-                persistent_data::SessionStore::getInstance().removeSession(
-                    session);
-                messages::success(asyncResp->res);
-            });
+        .methods(boost::beast::http::verb::delete_)(handleSessionDelete);
 
     BMCWEB_ROUTE(app, "/redfish/v1/SessionService/Sessions/")
         .privileges(redfish::privileges::getSessionCollection)
-        .methods(boost::beast::http::verb::get)(
-            [](const crow::Request& /*req*/,
-               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) -> void {
-                std::vector<const std::string*> sessionIds =
-                    persistent_data::SessionStore::getInstance().getUniqueIds(
-                        false, persistent_data::PersistenceType::TIMEOUT);
+        .methods(boost::beast::http::verb::get)(handleSessionCollectionGet);
 
-                asyncResp->res.jsonValue["Members@odata.count"] =
-                    sessionIds.size();
-                asyncResp->res.jsonValue["Members"] = nlohmann::json::array();
-                for (const std::string* uid : sessionIds)
-                {
-                    asyncResp->res.jsonValue["Members"].push_back(
-                        {{"@odata.id",
-                          "/redfish/v1/SessionService/Sessions/" + *uid}});
-                }
-                asyncResp->res.jsonValue["Members@odata.count"] =
-                    sessionIds.size();
-                asyncResp->res.jsonValue["@odata.type"] =
-                    "#SessionCollection.SessionCollection";
-                asyncResp->res.jsonValue["@odata.id"] =
-                    "/redfish/v1/SessionService/Sessions/";
-                asyncResp->res.jsonValue["Name"] = "Session Collection";
-                asyncResp->res.jsonValue["Description"] = "Session Collection";
-            });
-
+    // Note, the next route technically doesn't match the privilege
+    // registry given the way login mechanisms work.  The base privilege
+    // registry lists this endpoint as requiring login privilege, but because
+    // this is the endpoint responsible for giving the login privilege, and it
+    // is itself its own route, it needs to not require Login
     BMCWEB_ROUTE(app, "/redfish/v1/SessionService/Sessions/")
-        // Note, this technically doesn't match the privilege registry given the
-        // way login mechanisms work.  The base privilege registry lists this
-        // endpoint as requiring login privilege, but because this is the
-        // endpoint responsible for giving the login privilege, and it is itself
-        // its own route, it needs to not require Login
         .privileges({})
-        .methods(boost::beast::http::verb::post)(
-            [](const crow::Request& req,
-               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) -> void {
-                std::string username;
-                std::string password;
-                std::optional<nlohmann::json> oemObject;
-                std::string clientId;
-                if (!json_util::readJsonPatch(req, asyncResp->res, "UserName",
-                                              username, "Password", password,
-                                              "Oem", oemObject))
-                {
-                    return;
-                }
-
-                if (password.empty() || username.empty() ||
-                    asyncResp->res.result() != boost::beast::http::status::ok)
-                {
-                    if (username.empty())
-                    {
-                        messages::propertyMissing(asyncResp->res, "UserName");
-                    }
-
-                    if (password.empty())
-                    {
-                        messages::propertyMissing(asyncResp->res, "Password");
-                    }
-
-                    return;
-                }
-
-                int pamrc = pamAuthenticateUser(username, password);
-                bool isConfigureSelfOnly = pamrc == PAM_NEW_AUTHTOK_REQD;
-                if ((pamrc != PAM_SUCCESS) && !isConfigureSelfOnly)
-                {
-                    messages::resourceAtUriUnauthorized(
-                        asyncResp->res, req.urlView,
-                        "Invalid username or password");
-                    return;
-                }
-#ifdef BMCWEB_ENABLE_IBM_MANAGEMENT_CONSOLE
-                if (oemObject)
-                {
-                    std::optional<nlohmann::json> bmcOem;
-                    if (!json_util::readJson(*oemObject, asyncResp->res,
-                                             "OpenBMC", bmcOem))
-                    {
-                        return;
-                    }
-                    if (!json_util::readJson(*bmcOem, asyncResp->res,
-                                             "ClientID", clientId))
-                    {
-                        BMCWEB_LOG_ERROR << "Could not read ClientId";
-                        return;
-                    }
-                }
-#endif
-
-                // User is authenticated - create session
-                std::shared_ptr<persistent_data::UserSession> session =
-                    persistent_data::SessionStore::getInstance()
-                        .generateUserSession(
-                            username, req.ipAddress, clientId,
-                            persistent_data::PersistenceType::TIMEOUT,
-                            isConfigureSelfOnly);
-                asyncResp->res.addHeader("X-Auth-Token", session->sessionToken);
-                asyncResp->res.addHeader(
-                    "Location",
-                    "/redfish/v1/SessionService/Sessions/" + session->uniqueId);
-                asyncResp->res.result(boost::beast::http::status::created);
-                if (session->isConfigureSelfOnly)
-                {
-                    messages::passwordChangeRequired(
-                        asyncResp->res, crow::utility::urlFromPieces(
-                                            "redfish", "v1", "AccountService",
-                                            "Accounts", req.session->username));
-                }
-
-                fillSessionObject(asyncResp->res, *session);
-            });
+        .methods(boost::beast::http::verb::post)(handleSessionCollectionPost);
 
     BMCWEB_ROUTE(app, "/redfish/v1/SessionService/")
         .privileges(redfish::privileges::getSessionService)
-        .methods(boost::beast::http::verb::get)(
-            [](const crow::Request& /* req */,
-               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) -> void {
-                asyncResp->res.jsonValue["@odata.type"] =
-                    "#SessionService.v1_0_2.SessionService";
-                asyncResp->res.jsonValue["@odata.id"] =
-                    "/redfish/v1/SessionService/";
-                asyncResp->res.jsonValue["Name"] = "Session Service";
-                asyncResp->res.jsonValue["Id"] = "SessionService";
-                asyncResp->res.jsonValue["Description"] = "Session Service";
-                asyncResp->res.jsonValue["SessionTimeout"] =
-                    persistent_data::SessionStore::getInstance()
-                        .getTimeoutInSeconds();
-                asyncResp->res.jsonValue["ServiceEnabled"] = true;
-
-                asyncResp->res.jsonValue["Sessions"] = {
-                    {"@odata.id", "/redfish/v1/SessionService/Sessions"}};
-            });
+        .methods(boost::beast::http::verb::get)(handleSessionServiceGet);
 
     BMCWEB_ROUTE(app, "/redfish/v1/SessionService/")
         .privileges(redfish::privileges::patchSessionService)
-        .methods(boost::beast::http::verb::patch)(
-            [](const crow::Request& req,
-               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) -> void {
-                std::optional<int64_t> sessionTimeout;
-                if (!json_util::readJsonPatch(req, asyncResp->res,
-                                              "SessionTimeout", sessionTimeout))
-                {
-                    return;
-                }
-
-                if (sessionTimeout)
-                {
-                    // The mininum & maximum allowed values for session timeout
-                    // are 30 seconds and 86400 seconds respectively as per the
-                    // session service schema mentioned at
-                    // https://redfish.dmtf.org/schemas/v1/SessionService.v1_1_7.json
-
-                    if (*sessionTimeout <= 86400 && *sessionTimeout >= 30)
-                    {
-                        std::chrono::seconds sessionTimeoutInseconds(
-                            *sessionTimeout);
-                        persistent_data::SessionStore::getInstance()
-                            .updateSessionTimeout(sessionTimeoutInseconds);
-                        messages::propertyValueModified(
-                            asyncResp->res, "SessionTimeOut",
-                            std::to_string(*sessionTimeout));
-                    }
-                    else
-                    {
-                        messages::propertyValueNotInList(
-                            asyncResp->res, std::to_string(*sessionTimeout),
-                            "SessionTimeOut");
-                    }
-                }
-            });
+        .methods(boost::beast::http::verb::patch)(handleSessionServicePatch);
 }
 
 } // namespace redfish
