Repository: mirumee/ariadne

Issue:
Change `make_executable_schema` API to accept multiple bindables args
Currently, the second argument to `make_executable_schema` is list of `SchemaBindlables` or single bindable:

```python
# Single bindable:
schema = make_executable_schema(type_defs, query_type, debug=True)

# Multiple bindables:
schema = make_executable_schema(type_defs, [query_type, mutation_type], debug=True)
```

Looking at Ariadne uses in the wild, a pattern is starting to emerge where developers create dedicated modules/packages in their project for `scalars`, `mutations` or `types`, that use their `__init__.py`'s to gather all bindables into single lists:

```
from .scalars import scalars
from .types import types
from .mutations import mutations
```

Those are then combined into single list and passed to `make_executable_schema`:

```
schema = make_executable_schema(type_defs, scalars + types + mutations, debug=True)
```

This looks ugly, but things get uglier when there's bindable involved:

```
schema = make_executable_schema(type_defs, scalars + types + mutations + [fallback_resolvers], debug=True)
```

We can simplify this by changing bindables to `*bindables`:

```
schema = make_executable_schema(type_defs, scalars, types, mutations, fallback_resolvers, debug=True)
```

Discussion:

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 180e02a..83a51ec 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,6 +3,7 @@
 ## 0.8.0 (UNRELEASED)
 
 - Added recursive loading of GraphQL schema files from provided path.
+- Added support for passing multiple bindables as `*args` to `make_executable_schema`.
 - Updated Starlette dependency to 0.13.
 - Made `python-multipart` optional dependency for `asgi-uploads`.
 
diff --git a/ariadne/executable_schema.py b/ariadne/executable_schema.py
index caf2bca..2eaa44b 100644
--- a/ariadne/executable_schema.py
+++ b/ariadne/executable_schema.py
@@ -17,8 +17,7 @@ from .types import SchemaBindable
 
 def make_executable_schema(
     type_defs: Union[str, List[str]],
-    bindables: Union[SchemaBindable, List[SchemaBindable], None] = None,
-    *,
+    *bindables: Union[SchemaBindable, List[SchemaBindable]],
     directives: Dict[str, Type[SchemaDirectiveVisitor]] = None,
 ) -> GraphQLSchema:
     if isinstance(type_defs, list):
@@ -28,11 +27,12 @@ def make_executable_schema(
     schema = build_and_extend_schema(ast_document)
     validate_schema(schema)
 
-    if isinstance(bindables, list):
-        for obj in bindables:
-            obj.bind_to_schema(schema)
-    elif bindables:
-        bindables.bind_to_schema(schema)
+    for bindable in bindables:
+        if isinstance(bindable, list):
+            for obj in bindable:
+                obj.bind_to_schema(schema)
+        else:
+            bindable.bind_to_schema(schema)
 
     set_default_enum_values_on_schema(schema)
 


Test patch:
diff --git a/tests/test_modularization.py b/tests/test_modularization.py
index 8fac5c9..89f23d9 100644
--- a/tests/test_modularization.py
+++ b/tests/test_modularization.py
@@ -107,3 +107,27 @@ def test_defined_type_can_be_extended_with_new_field():
     result = graphql_sync(schema, "{ admin { username } }")
     assert result.errors is None
     assert result.data == {"admin": {"username": "Abby"}}
+
+
+def test_multiple_bindables_can_be_passed_as_separate_args():
+    type_defs = """
+        type Query {
+            user: User
+        }
+
+        type User {
+            username: String
+        }
+    """
+
+    query = QueryType()
+    query.set_field("user", lambda *_: Mock(first_name="Joe"))
+
+    user = ObjectType("User")
+    user.set_alias("username", "first_name")
+
+    schema = make_executable_schema(type_defs, query, user)
+
+    result = graphql_sync(schema, "{ user { username } }")
+    assert result.errors is None
+    assert result.data == {"user": {"username": "Joe"}}