Repository: tiangolo/fastapi

Issue:
OpenAPI: media_types of Body parameters and requestBody do not match
**Describe the bug**
The openapi.json for requestBody definitions uses the FastAPI default media_type instead of the defined one in the Body parameter(s).

**To Reproduce**
Create a path with request body that has either a single embedded parameter or multiple ones. List media_type that is different than the default application/json is. 

```python
from fastapi import FastAPI
from starlette import status
from . import schemas

app = FastAPI()

@app.post('/customers',
         status_code=status.HTTP_201_CREATED,
         )
def customer_create(data: schemas.Customer = Body(..., media_type='application/vnd+json.api', embed=True)):
    created_customer = {**data.dict(), **{'id': '1'}}
    return {'data': created_customer}
```

Then verify your openapi.json.

```yaml
# ...
post:
  responses:
    # ...
  summary: Customer Create
  operationId: customer_create_api_customers_post
  requestBody:
    content:
      application/json: # this should be different
        schema:
          "$ref": "#/components/schemas/Body_customer_create_api_customers_post"
    required: true
```

**Expected behavior**
The media_type of the requestBody of given path matches the specified one:

```yaml
# ...
post:
  responses:
    # ...
  summary: Customer Create
  operationId: customer_create_api_customers_post
  requestBody:
    content:
      application/vnd+json.api:
        schema:
          "$ref": "#/components/schemas/Body_customer_create_api_customers_post"
    required: true
```

**Environment:**
 - OS: masOS 10.14.6
 - Python: 3.6.5
 - FastAPI: 0.35.0


Discussion:

Resolving patch:
diff --git a/fastapi/dependencies/utils.py b/fastapi/dependencies/utils.py
--- a/fastapi/dependencies/utils.py
+++ b/fastapi/dependencies/utils.py
@@ -546,6 +546,8 @@ def get_body_field(*, dependant: Dependant, name: str) -> Optional[Field]:
     for f in flat_dependant.body_params:
         BodyModel.__fields__[f.name] = get_schema_compatible_field(field=f)
     required = any(True for f in flat_dependant.body_params if f.required)
+
+    BodySchema_kwargs: Dict[str, Any] = dict(default=None)
     if any(isinstance(f.schema, params.File) for f in flat_dependant.body_params):
         BodySchema: Type[params.Body] = params.File
     elif any(isinstance(f.schema, params.Form) for f in flat_dependant.body_params):
@@ -553,6 +555,14 @@ def get_body_field(*, dependant: Dependant, name: str) -> Optional[Field]:
     else:
         BodySchema = params.Body
 
+        body_param_media_types = [
+            getattr(f.schema, "media_type")
+            for f in flat_dependant.body_params
+            if isinstance(f.schema, params.Body)
+        ]
+        if len(set(body_param_media_types)) == 1:
+            BodySchema_kwargs["media_type"] = body_param_media_types[0]
+
     field = Field(
         name="body",
         type_=BodyModel,
@@ -561,6 +571,6 @@ def get_body_field(*, dependant: Dependant, name: str) -> Optional[Field]:
         model_config=BaseConfig,
         class_validators={},
         alias="body",
-        schema=BodySchema(None),
+        schema=BodySchema(**BodySchema_kwargs),
     )
     return field


Test patch:
diff --git a/tests/test_request_body_parameters_media_type.py b/tests/test_request_body_parameters_media_type.py
new file mode 100644
--- /dev/null
+++ b/tests/test_request_body_parameters_media_type.py
@@ -0,0 +1,67 @@
+import typing
+
+from fastapi import Body, FastAPI
+from pydantic import BaseModel
+from starlette.testclient import TestClient
+
+app = FastAPI()
+
+media_type = "application/vnd.api+json"
+
+# NOTE: These are not valid JSON:API resources
+# but they are fine for testing requestBody with custom media_type
+class Product(BaseModel):
+    name: str
+    price: float
+
+
+class Shop(BaseModel):
+    name: str
+
+
+@app.post("/products")
+async def create_product(data: Product = Body(..., media_type=media_type, embed=True)):
+    pass  # pragma: no cover
+
+
+@app.post("/shops")
+async def create_shop(
+    data: Shop = Body(..., media_type=media_type),
+    included: typing.List[Product] = Body([], media_type=media_type),
+):
+    pass  # pragma: no cover
+
+
+create_product_request_body = {
+    "content": {
+        "application/vnd.api+json": {
+            "schema": {"$ref": "#/components/schemas/Body_create_product_products_post"}
+        }
+    },
+    "required": True,
+}
+
+create_shop_request_body = {
+    "content": {
+        "application/vnd.api+json": {
+            "schema": {"$ref": "#/components/schemas/Body_create_shop_shops_post"}
+        }
+    },
+    "required": True,
+}
+
+client = TestClient(app)
+
+
+def test_openapi_schema():
+    response = client.get("/openapi.json")
+    assert response.status_code == 200
+    openapi_schema = response.json()
+    assert (
+        openapi_schema["paths"]["/products"]["post"]["requestBody"]
+        == create_product_request_body
+    )
+    assert (
+        openapi_schema["paths"]["/shops"]["post"]["requestBody"]
+        == create_shop_request_body
+    )