iT邦幫忙

2023 iThome 鐵人賽

DAY 5
0

接著繼續編輯 User Type 進一步增加欄位與學習 Strawberry 的 GraphQL 型態。

@strawberry.type
class User:
    id: strawberry.ID
    username: str
    email: str
    first_name: str
    last_name: str
    password: str
    last_login: typing.Optional[datetime.datetime]
-		is_active: bool = True
+   is_active: bool = strawberry.field(
+       default=True,
+       description="Is the user active?",
+   )

在這邊我們將 is_active 原本的預設值改成使用 strawberry.field,它提供一些額外的功能讓我們可以對欄位增加一些客製化功能,像是上面我們使用 description 來幫欄位增加說明,並顯示在 Schema 上面。

strawberry.field還可當成 裝飾器(Decorator) 來使用,其包裹的函式就是作為 resolver 來使用,像是下面的 full_name 欄位:

@strawberry.type
class User:
    id: strawberry.ID
    username: str
    email: str
    first_name: str
    last_name: str
    password: str
    last_login: typing.Optional[datetime.datetime]
    is_active: bool = strawberry.field(
        default=True,
        description="Is the user active?",
    )

+   @strawberry.field
+   def full_name(self) -> str:
+       return f"{self.first_name} {self.last_name}"

然後再增加一個使用者角色的欄位,這個欄位我們使用 Enum 來表示使用者角色有特定的選項值可以使用:

import datetime
+import enum
import typing
import strawberry

+@strawberry.enum
+class UserRole(enum.Enum):
+   NORMAL = strawberry.enum_value(
+       "normal",
+       description="Normal user",
+   )
+   STAFF = "staff"
+   MANAGER = "manager"
+   ADMIN = "admin"

@strawberry.type
class User:
    id: strawberry.ID
    username: str
    email: str
    first_name: str
    last_name: str
    password: str
    last_login: typing.Optional[datetime.datetime]
    is_active: bool = strawberry.field(
        default=True,
        description="Is the user active?",
    )
+   role: UserRole

@strawberry.field
    def full_name(self) -> str:
        return f"{self.first_name} {self.last_name}"

建立了一個 UserRoleenum Type,列舉出使用者角色普通使用者(normal)、員工(staff)管理者(manager)以及系統管理者(admin),然後可以使用 strawberry.enum_value來幫 Enum 值增加說明,然後幫 User Type 增加 role 欄位來表示使用者角色

最後一樣建立一個物件,來看看上面增加的欄位在 GraphiQL 上面 Schema 呈現的樣子。

def get_users() -> typing.List[types.User]:
    return [
        types.User(
            id=1,
            username="bob",
            email="bob@mymail.com",
            first_name="Bob",
            last_name="User",
            password="xxxxxx",
            last_login=datetime.datetime.now(),
+           role=types.UserRole.NORMAL,
        ),
    ]

然後我們就可以啟動 strawberry debug server,在瀏覽器上面試試看這次的修改內容。

$ strawberry server main:schema
Running strawberry on http://0.0.0.0:8000/graphql 🍓

https://ithelp.ithome.com.tw/upload/images/20230919/201619570WIE2NzbVn.png

GraphiQL 上面可以看到 Schema 增加這些欄位、說明與型態。

https://ithelp.ithome.com.tw/upload/images/20230919/20161957wOPDCHqPp2.png

上面是展示查詢結果,可以看 role 顯示的值是 Enum 的成員名稱,而非 Enum 的成員的值。

以下是這次的完整程式碼:

# app/types.py
import datetime
import enum
import typing
import strawberry

@strawberry.enum
class UserRole(enum.Enum):
    NORMAL = strawberry.enum_value(
        "normal",
        description="Normal user",
    )
    STAFF = "staff"
    MANAGER = "manager"
    ADMIN = "admin"

@strawberry.type
class User:
    id: strawberry.ID
    username: str
    email: str
    first_name: str
    last_name: str
    password: str
    last_login: typing.Optional[datetime.datetime]
    is_active: bool = strawberry.field(
        default=True,
        description="Is the user active?",
    )
    role: UserRole

    @strawberry.field
    def full_name(self) -> str:
        return f"{self.first_name} {self.last_name}"
# app/query.py
import typing
import datetime
import strawberry

from app import types

def get_users() -> typing.List[types.User]:
    return [
        types.User(
            id=1,
            username="bob",
            email="bob@mymail.com",
            first_name="Bob",
            last_name="User",
            password="xxxxxx",
            last_login=datetime.datetime.now(),
            role=types.UserRole.NORMAL,
        ),
    ]

@strawberry.type
class Query:
    users: typing.List[types.User] = strawberry.field(resolver=get_users)

users 其實也可以使用函式的形式實現,就如同上面所描述的將strawberry.field當成裝飾器。

@strawberry.type
class Query:
    # users: typing.List[types.User] = strawberry.field(resolver=get_users)
    @strawberry.field(description="Get all users")
    def users() -> typing.List[types.User]:
        return get_users()

參考資料


上一篇
Day 4:使用 Strawberry 學習 GraphQL 型別 – 1
下一篇
Day 6:使用 Strawberry 學習 GraphQL 型別 – 3
系列文
Django 與 Strawberry GraphQL:探索現代 API 開發之路30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言