diff --git a/.pylintrc b/.pylintrc
index 02b186f..46abd67 100644
--- a/.pylintrc
+++ b/.pylintrc
@@ -3,7 +3,7 @@ ignore=snapshots
 load-plugins=pylint.extensions.bad_builtin, pylint.extensions.mccabe
 
 [MESSAGES CONTROL]
-disable=C0103, C0111, C0209, C0412, I0011, R0101, R0801, R0901, R0902, R0903, R0912, R0913, R0914, R0915, R1260, W0231, W0621, W0703
+disable=C0103, C0111, C0209, C0412, I0011, R0101, R0801, R0901, R0902, R0903, R0912, R0913, R0914, R0915, R1260, W0231, W0511, W0621, W0703
 
 [SIMILARITIES]
 ignore-imports=yes
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7bf3892..6dcf457 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,10 +10,11 @@
 - Added support for `@tag` directive used by Apollo Federation.
 - Updated `starlette` dependency in setup.py to `<1.0`.
 - Moved project configuration from `setup.py` to `pyproject.toml`.
-- Added `execution_context_class` option to ASGI and WSGI `applications`.
+- Changed `root_value` option in ASGI and WSGI applications for callables to take operation and and variables in addition to context and parsed query.
+- Added `execution_context_class` option to ASGI and WSGI applications.
 - Added `query_parser` option to ASGI and WSGI `GraphQL` applications that enables query parsing customization.
 - Changed `middleware` option to work with callable or list of middlewares instead of `MiddlewareManager` instance.
-- Added `middleware_manager_class` option to ASGI and WSGI `applications`.
+- Added `middleware_manager_class` option to ASGI and WSGI applications.
 - Added Python 3.11 support.
 
 
diff --git a/ariadne/graphql.py b/ariadne/graphql.py
index 834d2f0..fc1d493 100644
--- a/ariadne/graphql.py
+++ b/ariadne/graphql.py
@@ -13,6 +13,7 @@ from typing import (
     cast,
     Union,
 )
+from warnings import warn
 
 from graphql import (
     DocumentNode,
@@ -46,6 +47,16 @@ from .types import (
 from .validation.introspection_disabled import IntrospectionDisabledRule
 
 
+def root_value_two_args_deprecated():  # TODO: remove in 0.19
+    warn(
+        "'root_value(context, document)' has been deprecated and will raise a type "
+        "error in Ariadne 0.18, update definition to "
+        "'root_value(context, operation_name, variables, document)'.",
+        DeprecationWarning,
+        stacklevel=2,
+    )
+
+
 async def graphql(
     schema: GraphQLSchema,
     data: Any,
@@ -99,7 +110,14 @@ async def graphql(
                 )
 
             if callable(root_value):
-                root_value = root_value(context_value, document)
+                try:
+                    root_value = root_value(  # type: ignore
+                        context_value, operation_name, variables, document
+                    )
+                except TypeError:  # TODO: remove in 0.19
+                    root_value_two_args_deprecated()
+                    root_value = root_value(context_value, document)  # type: ignore
+
                 if isawaitable(root_value):
                     root_value = await root_value
 
@@ -190,7 +208,14 @@ def graphql_sync(
                 )
 
             if callable(root_value):
-                root_value = root_value(context_value, document)
+                try:
+                    root_value = root_value(  # type: ignore
+                        context_value, operation_name, variables, document
+                    )
+                except TypeError:  # TODO: remove in 0.19
+                    root_value_two_args_deprecated()
+                    root_value = root_value(context_value, document)  # type: ignore
+
                 if isawaitable(root_value):
                     ensure_future(root_value).cancel()
                     raise RuntimeError(
@@ -280,7 +305,14 @@ async def subscribe(
             )
 
         if callable(root_value):
-            root_value = root_value(context_value, document)
+            try:
+                root_value = root_value(  # type: ignore
+                    context_value, operation_name, variables, document
+                )
+            except TypeError:  # TODO: remove in 0.19
+                root_value_two_args_deprecated()
+                root_value = root_value(context_value, document)  # type: ignore
+
             if isawaitable(root_value):
                 root_value = await root_value
 
diff --git a/ariadne/types.py b/ariadne/types.py
index 9368464..74046b9 100644
--- a/ariadne/types.py
+++ b/ariadne/types.py
@@ -40,7 +40,11 @@ Subscriber = Callable[..., AsyncGenerator]
 ErrorFormatter = Callable[[GraphQLError, bool], dict]
 
 ContextValue = Union[Any, Callable[[Any], Any]]
-RootValue = Union[Any, Callable[[Optional[Any], DocumentNode], Any]]
+RootValue = Union[
+    Any,
+    Callable[[Optional[Any], DocumentNode], Any],  # TODO: remove in 0.19
+    Callable[[Optional[Any], Optional[str], Optional[dict], DocumentNode], Any],
+]
 
 QueryParser = Callable[[ContextValue, Dict[str, Any]], DocumentNode]
 

diff --git a/tests/asgi/test_configuration.py b/tests/asgi/test_configuration.py
index 9f1ceba..f7c007d 100644
--- a/tests/asgi/test_configuration.py
+++ b/tests/asgi/test_configuration.py
@@ -111,6 +111,21 @@ def test_custom_root_value_function_is_called_by_query(schema):
     get_root_value.assert_called_once()
 
 
+def test_custom_deprecated_root_value_function_raises_warning_by_query(
+    schema,
+):
+    def get_root_value(_context, _document):
+        return True
+
+    app = GraphQL(
+        schema, context_value={"test": "TEST-CONTEXT"}, root_value=get_root_value
+    )
+    client = TestClient(app)
+
+    with pytest.deprecated_call():
+        client.post("/", json={"query": "{ status }"})
+
+
 def test_custom_root_value_function_is_called_by_subscription(schema):
     get_root_value = Mock(return_value=True)
     app = GraphQL(schema, root_value=get_root_value)
@@ -131,6 +146,29 @@ def test_custom_root_value_function_is_called_by_subscription(schema):
         get_root_value.assert_called_once()
 
 
+def test_custom_deprecated_root_value_function_raises_warning_by_subscription(schema):
+    def get_root_value(_context, _document):
+        return True
+
+    app = GraphQL(schema, root_value=get_root_value)
+    client = TestClient(app)
+
+    with pytest.deprecated_call():
+        with client.websocket_connect("/", ["graphql-ws"]) as ws:
+            ws.send_json({"type": GraphQLWSHandler.GQL_CONNECTION_INIT})
+            ws.send_json(
+                {
+                    "type": GraphQLWSHandler.GQL_START,
+                    "id": "test1",
+                    "payload": {"query": "subscription { ping }"},
+                }
+            )
+            response = ws.receive_json()
+            assert response["type"] == GraphQLWSHandler.GQL_CONNECTION_ACK
+            response = ws.receive_json()
+            assert response["type"] == GraphQLWSHandler.GQL_DATA
+
+
 def test_custom_root_value_function_is_called_by_subscription_graphql_transport_ws(
     schema,
 ):
@@ -156,6 +194,34 @@ def test_custom_root_value_function_is_called_by_subscription_graphql_transport_
         get_root_value.assert_called_once()
 
 
+def test_custom_deprecated_root_value_function_raises_warning_by_subscription_graphql_transport_ws(
+    schema,
+):
+    def get_root_value(_context, _document):
+        return True
+
+    websocket_handler = GraphQLTransportWSHandler()
+    app = GraphQL(
+        schema, root_value=get_root_value, websocket_handler=websocket_handler
+    )
+    client = TestClient(app)
+
+    with pytest.deprecated_call():
+        with client.websocket_connect("/", ["graphql-transport-ws"]) as ws:
+            ws.send_json({"type": GraphQLTransportWSHandler.GQL_CONNECTION_INIT})
+            ws.send_json(
+                {
+                    "type": GraphQLTransportWSHandler.GQL_SUBSCRIBE,
+                    "id": "test1",
+                    "payload": {"query": "subscription { ping }"},
+                }
+            )
+            response = ws.receive_json()
+            assert response["type"] == GraphQLTransportWSHandler.GQL_CONNECTION_ACK
+            response = ws.receive_json()
+            assert response["type"] == GraphQLTransportWSHandler.GQL_NEXT
+
+
 def test_custom_root_value_function_is_called_with_context_value(schema):
     get_root_value = Mock(return_value=True)
     app = GraphQL(
@@ -163,7 +229,7 @@ def test_custom_root_value_function_is_called_with_context_value(schema):
     )
     client = TestClient(app)
     client.post("/", json={"query": "{ status }"})
-    get_root_value.assert_called_once_with({"test": "TEST-CONTEXT"}, ANY)
+    get_root_value.assert_called_once_with({"test": "TEST-CONTEXT"}, None, None, ANY)
 
 
 def test_custom_query_parser_is_used_for_http_query(schema):
diff --git a/tests/wsgi/test_configuration.py b/tests/wsgi/test_configuration.py
index 47f8608..ed0a802 100644
--- a/tests/wsgi/test_configuration.py
+++ b/tests/wsgi/test_configuration.py
@@ -76,7 +76,21 @@ def test_custom_root_value_function_is_called_with_context_value(schema):
         schema, context_value={"test": "TEST-CONTEXT"}, root_value=get_root_value
     )
     app.execute_query({}, {"query": "{ status }"})
-    get_root_value.assert_called_once_with({"test": "TEST-CONTEXT"}, ANY)
+    get_root_value.assert_called_once_with({"test": "TEST-CONTEXT"}, None, None, ANY)
+
+
+def test_warning_is_raised_if_custom_root_value_function_has_deprecated_signature(
+    schema,
+):
+    def get_root_value(_context, _document):
+        return True
+
+    app = GraphQL(
+        schema, context_value={"test": "TEST-CONTEXT"}, root_value=get_root_value
+    )
+
+    with pytest.deprecated_call():
+        app.execute_query({}, {"query": "{ status }"})
 
 
 def test_custom_query_parser_is_used(schema):

Pass operation name and variables to root value resolver
Split form #843

Callable root value resolver becomes really useful in scenarios like GraphQL proxies, but it should have easy access to operation name and variables dict for that.

Plan is to change root value callable to support those as extra arguments, effectively changing type to that:

```python
RootValue = Union[
    Any,
    Callable[[Optional[Any], DocumentNode], Any],
    Callable[[Optional[Any], Optional[str], Optional[dict], DocumentNode], Any],
]
```
tests/asgi/test_configuration.py::test_custom_deprecated_root_value_function_raises_warning_by_query tests/asgi/test_configuration.py::test_custom_deprecated_root_value_function_raises_warning_by_subscription tests/asgi/test_configuration.py::test_custom_deprecated_root_value_function_raises_warning_by_subscription_graphql_transport_ws tests/asgi/test_configuration.py::test_custom_root_value_function_is_called_with_context_value tests/wsgi/test_configuration.py::test_custom_root_value_function_is_called_with_context_value tests/wsgi/test_configuration.py::test_warning_is_raised_if_custom_root_value_function_has_deprecated_signature
tests/asgi/test_configuration.py::test_custom_context_value_is_passed_to_resolvers tests/asgi/test_configuration.py::test_custom_context_value_function_is_set_and_called_by_app tests/asgi/test_configuration.py::test_custom_context_value_function_result_is_passed_to_resolvers tests/asgi/test_configuration.py::test_async_context_value_function_result_is_awaited_before_passing_to_resolvers tests/asgi/test_configuration.py::test_custom_root_value_is_passed_to_query_resolvers tests/asgi/test_configuration.py::test_custom_root_value_is_passed_to_subscription_resolvers tests/asgi/test_configuration.py::test_custom_root_value_is_passed_to_subscription_resolvers_graphql_transport_ws tests/asgi/test_configuration.py::test_custom_root_value_function_is_called_by_query tests/asgi/test_configuration.py::test_custom_root_value_function_is_called_by_subscription tests/asgi/test_configuration.py::test_custom_root_value_function_is_called_by_subscription_graphql_transport_ws tests/asgi/test_configuration.py::test_custom_query_parser_is_used_for_http_query tests/asgi/test_configuration.py::test_custom_validation_rule_is_called_by_query_validation tests/asgi/test_configuration.py::test_custom_validation_rules_function_is_set_and_called_on_query_execution tests/asgi/test_configuration.py::test_custom_validation_rules_function_is_called_with_context_value tests/asgi/test_configuration.py::test_default_logger_is_used_to_log_error_if_custom_is_not_set tests/asgi/test_configuration.py::test_custom_logger_instance_is_used_to_log_error tests/asgi/test_configuration.py::test_custom_logger_is_used_to_log_query_error tests/asgi/test_configuration.py::test_custom_logger_is_used_to_log_subscription_source_error tests/asgi/test_configuration.py::test_custom_logger_is_used_to_log_subscription_source_error_graphql_transport_ws tests/asgi/test_configuration.py::test_custom_logger_is_used_to_log_subscription_resolver_error tests/asgi/test_configuration.py::test_custom_logger_is_used_to_log_subscription_resolver_error_graphql_transport_ws tests/asgi/test_configuration.py::test_custom_error_formatter_is_used_to_format_query_error tests/asgi/test_configuration.py::test_custom_error_formatter_is_used_to_format_subscription_syntax_error tests/asgi/test_configuration.py::test_custom_error_formatter_is_used_to_format_subscription_syntax_error_graphql_transport_ws tests/asgi/test_configuration.py::test_custom_error_formatter_is_used_to_format_subscription_source_error tests/asgi/test_configuration.py::test_custom_error_formatter_is_used_to_format_subscription_source_error_graphql_transport_ws tests/asgi/test_configuration.py::test_custom_error_formatter_is_used_to_format_subscription_resolver_error tests/asgi/test_configuration.py::test_custom_error_formatter_is_used_to_format_subscription_resolver_error_graphql_transport_ws tests/asgi/test_configuration.py::test_error_formatter_is_called_with_debug_enabled tests/asgi/test_configuration.py::test_error_formatter_is_called_with_debug_disabled tests/asgi/test_configuration.py::test_extension_from_option_are_passed_to_query_executor tests/asgi/test_configuration.py::test_extensions_function_result_is_passed_to_query_executor tests/asgi/test_configuration.py::test_async_extensions_function_result_is_passed_to_query_executor tests/asgi/test_configuration.py::test_middlewares_are_passed_to_query_executor tests/asgi/test_configuration.py::test_middleware_function_result_is_passed_to_query_executor tests/asgi/test_configuration.py::test_async_middleware_function_result_is_passed_to_query_executor tests/asgi/test_configuration.py::test_handle_connection_init_timeout_handler_executed_graphql_transport_ws tests/wsgi/test_configuration.py::test_custom_context_value_is_passed_to_resolvers tests/wsgi/test_configuration.py::test_custom_context_value_function_is_set_and_called_by_app tests/wsgi/test_configuration.py::test_custom_context_value_function_is_called_with_request_value tests/wsgi/test_configuration.py::test_custom_context_value_function_result_is_passed_to_resolvers tests/wsgi/test_configuration.py::test_custom_root_value_is_passed_to_resolvers tests/wsgi/test_configuration.py::test_custom_root_value_function_is_set_and_called_by_app tests/wsgi/test_configuration.py::test_custom_query_parser_is_used tests/wsgi/test_configuration.py::test_custom_validation_rule_is_called_by_query_validation tests/wsgi/test_configuration.py::test_custom_validation_rules_function_is_set_and_called_on_query_execution tests/wsgi/test_configuration.py::test_custom_validation_rules_function_is_called_with_context_value tests/wsgi/test_configuration.py::test_default_logger_is_used_to_log_error_if_custom_is_not_set tests/wsgi/test_configuration.py::test_custom_logger_is_used_to_log_error tests/wsgi/test_configuration.py::test_custom_logger_instance_is_used_to_log_error tests/wsgi/test_configuration.py::test_custom_error_formatter_is_used_to_format_error tests/wsgi/test_configuration.py::test_error_formatter_is_called_with_debug_enabled_flag tests/wsgi/test_configuration.py::test_error_formatter_is_called_with_debug_disabled_flag tests/wsgi/test_configuration.py::test_extension_from_option_are_passed_to_query_executor tests/wsgi/test_configuration.py::test_extensions_function_result_is_passed_to_query_executor tests/wsgi/test_configuration.py::test_middlewares_are_passed_to_query_executor tests/wsgi/test_configuration.py::test_middleware_function_result_is_passed_to_query_executor tests/wsgi/test_configuration.py::test_wsgi_app_supports_sync_dataloader_with_custom_execution_context