【问题标题】:drf-yasg provides wrong paths to URIsdrf-yasg 提供了错误的 URI 路径
【发布时间】:2019-10-14 21:58:27
【问题描述】:

在我的应用程序中,我需要为多个客户端提供多个带有分组端点的 Swagger 页面。

我的一个客户端(路径)提供移动应用 API,另一个提供 Web 客户端 API。 URL 模式相应地保存在 2 个不同的 urls.py 中。

我正在使用 drf-yasg 为我的 API 生成架构。

要为那些我为每个 urls.py 文件初始化 2 个单独的 schema_views 的人生成 swagger 规范,如下所示:

from api_mobile.urls import urlpatterns as mobile_patterns
from api_web.urls import urlpatterns as web_patterns

mobile_schema_view = get_schema_view(
openapi.Info(
    title="Mobile API",
    default_version='v3',
),
public=True,
permission_classes=(permissions.AllowAny,),
patterns=mobile_patterns,
)

web_schema_view = get_schema_view(
    openapi.Info(
        title="Web API",
        default_version='v1',
    ),
    public=True,
    permission_classes=(permissions.AllowAny,),
    patterns=web_patterns,
)

urlpatterns = [
    path(
        'api/mobile/docs',
        mobile_schema_view.with_ui('swagger', cache_timeout=0),
        name='mobile-schema-ui'
    ),
    path(
        'api/web/docs',
        web_schema_view.with_ui('swagger', cache_timeout=0),
        name='web-schema-ui'
    ),

    path('api/mobile/v3/', include('api_mobile.urls'), name='mobile_urls'),
    path('api/web/v1/', include('api_web.urls'), name='web_urls'),
    ...
]

其中mobile_patternsweb_patterns 只是网址格式列表。

如果我打开 http://localhost:8000/api/mobile/docshttp://localhost:8000/api/web/docs 我确实看到了为两个模式列表正确生成的架构,但是如果我尝试直接从 swagger 规范页面发出请求,所有端点都会返回 404 错误——它们都尝试在不提供端点完整路径的情况下向不存在的 url 模式发出请求。

因此,如果我从 mobile 端点向任何视图发出请求,swagger 会尝试在

http://localhost:8000/some_mobile_url/ 而不是http://localhost:8000/api/mobile/v3/some_mobile_url/

另外一个模式的情况也一样,swagger 错误地请求http://localhost:8000/some_web_url/ 而不是使用完整路径 http://localhost:8000/api/web/v3/some_web_url/

显然,能够直接通过swagger 测试 API 非常重要,因此对我而言,规范本身是不够的。

这是我错误配置swagger itlesf 的问题,还是我应该以某种方式提供swagger 的路径,以便相应地为每个网址添加完整路径?

【问题讨论】:

    标签: django django-rest-framework swagger openapi drf-yasg


    【解决方案1】:

    这对我们来说很好用:

    api_schema.py

    from django.conf.urls import include, url
    from drf_yasg.views import get_schema_view
    from drf_yasg import openapi
    
    from books.api.v1.urls import urlpatterns as api_v1
    
    
    API_DESCRIPTION = openapi.Info(
        ...
    )
    
    schema_view = get_schema_view(
        info=...,
        ...
        url='https://oursite.company.io/',
        patterns=[
            url('api/v1/', include(api_v1)),
        ],
    )
    

    books.api.v1.urls.py

    from django.conf.urls import include, url
    
    urlpatterns = [
        url(r'^books', ...),
        ...
    ]
    

    urls.py

    from ...api_schema import schema_view
    
    ...
    url(r'^api/v1/', include(api_v1)),
    url(r'^api/schema(?P<format>\.json|\.yaml)$',
            schema_view.without_ui(cache_timeout=0),
            name='api_schema_v1'),
    ...
    

    【讨论】:

    • 您是否在某种主模式列表中注册了schema_viewapi_v1 模式,其中包含到文档页面和api_v1 URI 的路由?因为从您的示例中,我看不到 django 如何知道在哪里显示给定端点集的招摇页面。
    • 还有一种方法可以直接从 django 配置中获取get_schema_viewurl 字段的基本url 路径。我的意思是:让 django 自己提供基本路径。
    • @StanRedoute 从 Django 配置中获取 url 字段似乎更好,同意:thumbs-up:
    • 也就是说:你应该将什么作为url 参数传递给get_schema_view 以避免硬编码值?
    • @StanRedoute url=f'{settings.PROTOCOL}://{settings.BACKEND_DOMAIN}:{settings.BACKEND_PORT}'
    猜你喜欢
    • 2019-05-17
    • 1970-01-01
    • 2019-07-27
    • 2019-08-14
    • 2017-02-02
    • 2020-07-26
    • 1970-01-01
    • 1970-01-01
    • 2023-01-30
    相关资源
    最近更新 更多