<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          GraphQL 實戰(zhàn)篇之前端Vue+后端

          共 7990字,需瀏覽 16分鐘

           ·

          2021-02-18 19:56

          (給前端大學加星標,提升前端技能.

          作者:PatWu16

          https://segmentfault.com/a/1190000039087433

          這篇文章記錄使用Vue+GraphQL搭建客戶端。

          客戶端項目目錄結構如下:

          安裝

          首先我們先使用vue-cli新建項目,接著安裝依賴:

          npm?install?apollo-cache-inmemory?apollo-client?apollo-link?apollo-link-http?apollo-link-ws?apollo-utilities?vue-apollo?-S

          引入依賴

          //?main.js
          import?Vue?from?'vue'
          import?App?from?'./App.vue'
          import?{?apolloProvider?}?from?'./vue-apollo';

          Vue.config.productionTip?=?false

          new?Vue({
          ????render:?h?=>?h(App),
          ????//?像?vue-router?或?vuex?一樣注入apolloProvider?
          ????apolloProvider,
          }).$mount('#app')
          //?vue-apollo.js
          //?相關文檔請查閱?https://apollo.vuejs.org/zh-cn/
          import?{?ApolloClient?}?from?'apollo-client'
          import?{?createHttpLink?}?from?'apollo-link-http'
          import?{?InMemoryCache?}?from?'apollo-cache-inmemory'
          import?Vue?from?'vue'
          import?VueApollo?from?'vue-apollo'
          //?新的引入文件
          import?{?split?}?from?'apollo-link'
          import?{?WebSocketLink?}?from?'apollo-link-ws'
          import?{?getMainDefinition?}?from?'apollo-utilities'

          Vue.use(VueApollo)

          //?與?API?的?HTTP?連接
          const?httpLink?=?createHttpLink({?//?你需要在這里使用絕對路徑?
          ????uri:?'http://localhost:3001/graphql',
          })
          //?創(chuàng)建訂閱的?websocket?連接
          const?wsLink?=?new?WebSocketLink({
          ????uri:?'ws://localhost:3001/graphql',
          ????options:?{
          ????????reconnect:?true,
          ????}
          })
          //?使用分割連接的功能
          //?你可以根據(jù)發(fā)送的操作類型將數(shù)據(jù)發(fā)送到不同的連接
          const?link?=?split(({?query?})?=>?{
          ????const?definition?=?getMainDefinition(query)
          ????return?definition.kind?===?'OperationDefinition'?&&?definition.operation?===?'subscription'
          ????},
          ????wsLink,
          ????httpLink
          )
          //?創(chuàng)建?apollo?客戶端
          const?apolloClient?=?new?ApolloClient({
          ????link,
          ????cache:?new?InMemoryCache(),
          ????connectToDevTools:?true,
          })

          export?const?apolloProvider?=?new?VueApollo({???????
          ????defaultClient:?apolloClient,
          })

          編寫業(yè)務代碼

          //?App.vue



          //?HelloGraphQL.vue


          至此,我們便可以請求server端服務了!??????

          前面我們介紹了GraphQL的概念和基礎知識,這篇文章記錄下使用Nestjs+GraphQL搭建Node服務。

          安裝

          npm?i?--save?@nestjs/graphql?graphql-tools?graphql?apollo-server-express

          注冊

          //?app.module.ts
          import?{?Module?}?from?'@nestjs/common';
          import?{?GraphQLModule?}?from?'@nestjs/graphql';
          import?{?ConfigModule,?ConfigService?}?from?'nestjs-config';
          @Module({
          ?imports:?[
          ????ConfigModule.load(path.resolve(__dirname,?'config',?'**/!(*.d).{ts,js}')),
          ????GraphQLModule.forRootAsync({
          ????????imports:?[ConfigModule],
          ????????useFactory:?(config:?ConfigService)?=>?config.get('graphql'),
          ????????inject:?[ConfigService],
          ????})?
          ?],})
          export?class?ApplicationModule?{}

          //?src/config/graphql.ts
          import?*?as?path?from?'path';
          export?default?{
          ??autoSchemaFile:?path.join(process.cwd(),?'src/schema.gql'),?//?最后生成的`Schema?文件,不可修改`
          ??installSubscriptionHandlers:?true,?//?啟用訂閱
          };

          啟動項目,并訪問 http://localhost:3000/graphql,我們便可以看到graphql頁面。

          編寫服務端邏輯

          接下來我們注冊一個author模塊,目錄結構如下:

          //?author.module.ts
          import?{?Module?}?from?'@nestjs/common';
          import?{?AuthorService?}?from?'./author.service';
          import?{?AuthorResolver?}?from?'./author.resolver';
          @Module({
          ??providers:?[
          ????AuthorService,?
          ????AuthorResolver
          ??]
          })
          export?class?AuthorModule?{}
          //?author.service.ts
          //?此文件用于寫數(shù)據(jù)庫查詢等邏輯,我們著重學習GraphQL的使用,故此處不做相關Demo
          import?{?Injectable?}?from?'@nestjs/common';
          @Injectable()
          export?class?AuthorService?{
          ??async?findOneById()?{}
          }
          //?author.resolver.ts
          import?{?Args,?Mutation,?Query,?Resolver,?Subscription,?ResolveField,?Parent,?Int?}?from?'@nestjs/graphql';
          import?{?PubSub?}?from?'graphql-subscriptions';
          import?{?Author?}?from?'./models/author.model';
          import?{?Post?}?from?'./models/post.model';
          import?{?AuthorService?}?from?'./author.service';
          //?import?{?GetAuthorArgs?}?from?'./dto/get-author.args';

          const?pubSub?=?new?PubSub();

          @Resolver(()?=>?Author)
          export?class?AuthorResolver?{
          ??constructor(
          ?????private?authorsService:?AuthorService
          ??)?{}
          ?//?根據(jù)id查詢作者信息
          ?@Query(returns?=>?Author,?{
          ????name:?'author',
          ????description:?'get?author?info?by?id',
          ????nullable:?false
          ?})
          ?async?getAuthor(@Args('id',?{
          ?????type:?()?=>?Int,
          ?????description:?'author?id',
          ?????nullable:?false
          ?})?id:?number):?Promise?{
          ?//?return?this.authorsService.findOneById(id);
          ????return?{
          ????????id,
          ????????firstName:?'wu',
          ????????lastName:?'pat',
          ????};
          }
          //?使用DTO接受參數(shù)
          //?@Query(returns?=>?Author)
          //?async?getAuthor(@Args()?args:?GetAuthorArgs)?{
          //???return?this.authorsService.findOneById(args);
          //?}
          ?//?修改作者信息
          ?@Mutation(returns?=>?Author,?{
          ????name:?'changeAuthor',
          ????description:?'change?author?info?by?id',
          ????nullable:?false
          ?})
          ?async?changeAuthor(
          ????@Args('id')?id:?number,
          ????@Args('firstName')?firstName:?string,
          ????@Args('lastName')?lastName:?string,
          ?):?Promise?{
          ?//?return?this.authorsService.findOneById(id);
          ?return?{
          ????id,
          ????firstName,
          ????lastName,
          ??};
          }

          ?//?解析posts字段
          ?@ResolveField()
          ?async?posts(@Parent()?author:?Author):?Promise?{
          ?????const?{?id?}?=?author;
          ?????//?return?this.postsService.findAll({?authorId:?id?});
          ?????return?[{
          ????????id:?4,
          ????????title:?'hello',
          ????????votes:?2412,
          ?????}];
          ?}
          ?
          ?//?新增文章
          ?@Mutation(returns?=>?Post)
          ?async?addPost()?{
          ?????const?newPost?=?{
          ????????id:?1,
          ????????title:?'新增文章'
          ?????};
          ?????//?新增成功后,通知更新
          ?????await?pubSub.publish('postAdded',?{?postAdded:?newPost?});
          ?????return?newPost;
          ?}
          ?
          ?//?監(jiān)聽變更
          ?@Subscription(returns?=>?Post,?{
          ?????name:?'postAdded',
          ?????//?filter:?(payload,?variables)?=>?payload.postAdded.title?===?variables.title,
          ?????//?過濾訂閱
          ?????//?resolve(this:?AuthorResolver,?value)?{?//?修改payload參數(shù)
          ?????//???return?value;
          ?????//?}?})
          ?async?postAdded(/*@Args('title')?title:?string*/)?{
          ????return?(await?pubSub.asyncIterator('postAdded'));
          ?}}
          //?author.model.ts
          import?{?Field,?Int,?ObjectType?}?from?'@nestjs/graphql';
          import?{?Post?}?from?'./post.model';

          @ObjectType({?description:?'Author?model'?})
          export?class?Author?{
          ?@Field(type?=>?Int,?{
          ????description:?'作者id'
          ?})
          ?id:?number;
          ?
          ?@Field({
          ????nullable:?true,
          ????description:?'作者姓姓氏'
          ?})
          ?firstName?:?string;
          ?
          ?@Field({?
          ????nullable:?true,
          ????description:?'作者姓名字'
          ?})
          ?lastName?:?string;
          ?
          ?//?要聲明數(shù)組的項(而不是數(shù)組本身)是可為空的,請將nullable屬性設置'items'
          ?//?如果數(shù)組及其項都是可空的,則設置nullable為'itemsAndList'?
          ?@Field(type?=>?[Post],?{
          ????nullable:?'items',
          ????description:?'作者發(fā)表的文章'
          ?})
          ?posts:?Post[];
          }
          //?posts.model.ts
          import?{?Field,?Int,?ObjectType?}?from?'@nestjs/graphql';

          @ObjectType()
          export?class?Post?{

          ?@Field(type?=>?Int)
          ?id:?number;
          ?
          ?@Field()?title:?string;
          ?
          ?@Field(type?=>?Int,?{
          ????nullable:?true
          ?})
          ?votes?:?number;
          }

          上面的代碼包含了查詢、變更、訂閱類型,此時我們會發(fā)現(xiàn)src下面新增了一個文件schema.gql,這個文件就是自動生成的類型文件:

          #?------------------------------------------------------
          #?THIS?FILE?WAS?AUTOMATICALLY?GENERATED?(DO?NOT?MODIFY)
          #?------------------------------------------------------
          type?Post?{
          ????id:?Int!
          ????title:?String!
          ????votes:?Int
          }

          """Author?model"""
          type?Author?{
          ????"""作者id"""
          ????id:?Int!
          ????
          ????"""作者姓姓氏"""
          ????firstName:?String
          ????
          ????"""作者姓名字"""
          ????lastName:?String
          ????
          ????"""作者發(fā)表的文章"""
          ????posts:?[Post]!
          }

          type?Query?{
          ????"""get?author?info?by?id"""
          ????author(
          ????????"""author?id"""
          ????????id:?Int!
          ????):?Author!
          }

          type?Mutation?{
          ????"""change?author?info?by?id"""?
          ????changeAuthor(lastName:?String!,?firstName:?String!,?id:?Float!):?Author!
          ????addPost:?Post!
          }

          type?Subscription?{
          ????postAdded:?Post!
          }

          執(zhí)行查詢

          這時我們的服務已經(jīng)運行起來,可以執(zhí)行查詢了。

          #?左下角編寫QUERY?VARIABLES
          {
          ????"id":?1
          }
          #?Write?your?query?or?mutation?here
          #?查詢作者信息
          query?author($id:?Int!)?{
          ????alias:?author(id:?$id)?{
          ????????id,
          ????????firstName,
          ????????posts?{
          ????????????id,
          ????????????title
          ????????}
          ????}
          }

          #?修改作者信息
          mutation?changeAuthor?{
          ????changeAuthor(id:?3,?firstName:?"firstName"?lastName:?"lastName")?{
          ????????id,
          ????????firstName,
          ????????lastName
          ????}
          }

          #?發(fā)布文章
          mutation?addPost?{
          ????post:?addPost?{
          ????????id,
          ????????title
          ????}
          }

          #?訂閱文章新增
          subscription?postAdded{
          ????postAdded?{
          ????????id,
          ????????title
          ????}
          }

          //?自省查詢
          query?schema{
          ????__schema?{
          ????????types?{?
          ????????????name
          ????????}
          ????}
          }

          至此,我們的Nestjs+GraphQL服務便搭建完成,給自己一個??!

          瀏覽 113
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  日韩精品在线免费观看视频 | 大香蕉丁香综合网 | 三级片在线 天天 | 操逼操逼操逼操逼操 | 北条麻妃91视频 |