
GraphQL API滲透測試指南
讓我們通過一個簡單的圖書管理系統來學習GraphQL。首先定義數據類型:
python
復制
importgraphene
classBook(graphene.ObjectType): title=graphene.String() author=graphene.String() published_year=graphene.Int()
classAuthor(graphene.ObjectType): name=graphene.String() books=graphene.List(Book)
接下來,我們來定義查詢類:
python
復制
classQuery(graphene.ObjectType): book=graphene.Field(Book,title=graphene.String()) all_books=graphene.List(Book)
defresolve_book(self,info,title):
returnBook( title=title, author=“向前”, published_year=2024 )
defresolve_all_books(self,info):
return[ Book(title=“Python進階”,author=“向前”,published_year=2024), Book(title=“GraphQL實戰”,author=“向前”,published_year=2024) ]
schema=graphene.Schema(query=Query)
現在讓我們來執行一些查詢:
python
復制
query=”’ query{ book(title:“Python進階”){ title author publishedYear } } ”’
result=schema.execute(query) print(result.data)
小貼士:GraphQL的查詢語句看起來很像JSON,但它有自己特殊的語法規則。字段名使用駝峰式命名規則(camelCase)。
除了查詢,我們還可以通過mutation來修改數據:
python
復制
classCreateBook(graphene.Mutation): classArguments: title=graphene.String() author=graphene.String() published_year=graphene.Int()
book=graphene.Field(Book)
defmutate(self,info,title,author,published_year): book=Book(title=title,author=author,published_year=published_year)
returnCreateBook(book=book)
classMutation(graphene.ObjectType): create_book=CreateBook.Field()
schema=graphene.Schema(query=Query,mutation=Mutation)
使用mutation添加新書:
python
復制
mutation=”’ mutation{ createBook(title:“GraphQL入門”,author:“向前”,publishedYear:2024){ book{ title author publishedYear } } } ”’
result=schema.execute(mutation) print(result.data)
1.錯誤處理:GraphQL會返回詳細的錯誤信息,包括具體的字段和原因。
2.查詢優化:可以使用only()
和select_related()
來優化數據庫查詢。
3.字段別名:可以給字段取別名,避免命名沖突:
python
復制
query=”’ query{ pythonBook:book(title:“Python進階”){ title } graphqlBook:book(title:“GraphQL實戰”){ title } } ”’
注意事項:
在生產環境中,記得添加適當的身份驗證和權限控制 對查詢的深度和復雜度進行限制,避免惡意查詢 *合理使用數據加載器(DataLoader)來避免N+1查詢問題
1.嘗試給Book類型添加一個price字段,并修改相關的查詢和變更操作 2.實現一個刪除圖書的mutation 3.添加一個按作者名查詢所有圖書的查詢
小伙伴們,今天的Python學習之旅就到這里啦!
GraphQL確實是一個強大的API查詢工具,它能讓我們的數據獲取更加精確和高效。
記得動手實踐哦,有問題隨時在評論區問向前。
祝大家學習愉快,Python學習節節高!
復制markdown
復制
大家好,我是向前!上一篇文章我們學習了GraphQL的基礎知識,今天讓我們繼續深入探索GraphQL在Python中的一些高級特性和實用技巧!
在GraphQL中,接口(Interface)和聯合類型(Union)是兩個非常實用的高級特性。
接口實現
“`python importgraphene
classHasAuthor(graphene.Interface): author=graphene.String() publish_date=graphene.String()
classArticle(graphene.ObjectType): classMeta: interfaces=(HasAuthor,)
title=graphene.String() content=graphene.String()
classBook(graphene.ObjectType): classMeta: interfaces=(HasAuthor,)
title=graphene.String() isbn=graphene.String()
聯合類型
python
復制
classSearchResult(graphene.Union): classMeta: types=(Article,Book)
classQuery(graphene.ObjectType): search=graphene.List(SearchResult,keyword=graphene.String())
defresolve_search(self,info,keyword):
results=[ Article( title=“GraphQL教程”, content=“GraphQL入門指南”, author=“向前”, publish_date=“2024-01-01” ), Book( title=“Python實戰”, isbn=“123-456-789”, author=“向前”, publish_date=“2024-02-01” ) ] returnresults
為了解決N+1查詢問題,我們可以使用Promise和DataLoader:
python
復制
frompromiseimportPromise frompromise.dataloaderimportDataLoader
classBookLoader(DataLoader): defbatch_load_fn(self,keys):
books=[ {“id”:k,“title”:f“Book{k}”,“author”:“向前”} forkinkeys ] returnPromise.resolve(books)
book_loader=BookLoader()
classQuery(graphene.ObjectType): books=graphene.List( Book, ids=graphene.List(graphene.ID) )
defresolve_books(self,info,ids): returnbook_loader.load_many(ids)
有時候我們需要自定義數據類型,比如日期或JSON:
python
復制
importjson fromgraphene.typesimportScalar fromdatetimeimportdatetime
classJSONScalar(Scalar): @staticmethod defserialize(dt): returnjson.dumps(dt)
@staticmethod defparse_literal(node): returnjson.loads(node.value)
@staticmethod defparse_value(value): returnjson.loads(value)
classDateTimeScalar(Scalar): @staticmethod defserialize(dt): returndt.isoformat()
@staticmethod defparse_value(value): returndatetime.fromisoformat(value)
classBook(graphene.ObjectType): metadata=JSONScalar() published_at=DateTimeScalar()
GraphQL還支持實時訂閱功能,這在需要實時更新的場景非常有用:
python
復制
importasyncio fromgrapheneimportObjectType,Field,String
classSubscription(ObjectType): count=Field(String)
asyncdefresolve_count(root,info):
foriinrange(5): yieldf“Count:{i}” awaitasyncio.sleep(1)
schema=graphene.Schema( query=Query, mutation=Mutation, subscription=Subscription )
中間件可以幫助我們處理認證、日志等通用邏輯:
python
復制
classAuthMiddleware: defresolve(self,next,root,info,args): ifnotinfo.context.get(‘is_authenticated’): raiseException(‘Authenticationrequired’) returnnext(root,info,args)
classLoggingMiddleware: defresolve(self,next,root,info,args): start=time.time() result=next(root,info,args) duration=time.time()-start print(f“Field{info.field_name}took{duration}storesolve”) returnresult
schema=graphene.Schema( query=Query, mutation=Mutation, middleware=[AuthMiddleware(),LoggingMiddleware()] )
python
復制
fromgraphene.validationimportvalidate_max_depth
defvalidate_query(query_string): returnvalidate_max_depth(query_string,max_depth=5)
python
復制
classQuery(graphene.ObjectType): books=graphene.List( Book, first=graphene.Int(), offset=graphene.Int() )
defresolve_books(self,info,first=None,offset=None): books=get_books()#獲取所有圖書 ifoffsetisnotNone: books=books[offset:] iffirstisnotNone: books=books[:first] returnbooks
1.實現一個支持圖書評論的系統,使用接口定義共同的用戶行為 2.添加一個實時訂閱功能,當有新書上架時通知訂閱者 3.實現一個通用的緩存中間件,緩存查詢結果
小貼士:
在使用DataLoader時,注意將loader實例存儲在上下文中,避免創建多個實例?訂閱功能需要使用支持異步的服務器,如FastAPI或Starlette *自定義標量類型時要考慮輸入驗證和錯誤處理
小伙伴們,今天的Python學習之旅就到這里啦!
我們學習了GraphQL的一些高級特性,相信這些知識會讓你的API開發更上一層樓。
記得動手實踐哦,有問題隨時在評論區問向前。
祝大家學習愉快,Python學習節節高!
文章轉自微信公眾號@影書劇
GraphQL API滲透測試指南
Python + BaiduTransAPI :快速檢索千篇英文文獻(附源碼)
掌握ChatGPT API集成的方便指南
node.js + express + docker + mysql + jwt 實現用戶管理restful api
nodejs + mongodb 編寫 restful 風格博客 api
表格插件wpDataTables-將 WordPress 表與 Google Sheets API 連接
手把手教你用Python和Flask創建REST API
使用 Django 和 Django REST 框架構建 RESTful API:實現 CRUD 操作
ASP.NET Web API快速入門介紹