从Type-GraphQL的服务器到客户端

我們的目的是什麼。

    • type-graphqlでサーバ側のスキーマ定義

 

    • expressで公開

 

    • clientは自動生成

 

    subscriptionは対象外

服务器建设

安装 type-graphql

创建一个解析器

把公式文件翻译成中文

@InputType()
class NewRecipeInput {
  @Field()
  @MaxLength(30)
  title: string;

  @Field({ nullable: true })
  @Length(30, 255)
  description?: string;

  @Field(type => [String])
  @ArrayMaxSize(30)
  ingredients: string[];
}

@ArgsType()
class RecipesArgs {
  @Field(type => Int)
  @Min(0)
  skip: number = 0;

  @Field(type => Int)
  @Min(1)
  @Max(50)
  take: number = 25;
}

@Resolver(Recipe)
class RecipeResolver {
  constructor(private recipeService: RecipeService) {}

  @Query(returns => Recipe)
  async recipe(@Arg("id") id: string) {
    const recipe = await this.recipeService.findById(id);
    if (recipe === undefined) {
      throw new RecipeNotFoundError(id);
    }
    return recipe;
  }

  @Query(returns => [Recipe])
  recipes(@Args() { skip, take }: RecipesArgs) {
    return this.recipeService.findAll({ skip, take });
  }

  @Mutation(returns => Recipe)
  @Authorized()
  addRecipe(
    @Arg("newRecipeData") newRecipeData: NewRecipeInput,
    @Ctx("user") user: User,
  ): Promise<Recipe> {
    return this.recipeService.addNew({ data: newRecipeData, user });
  }

  @Mutation(returns => Boolean)
  @Authorized(Roles.Admin)
  async removeRecipe(@Arg("id") id: string) {
    try {
      await this.recipeService.removeById(id);
      return true;
    } catch {
      return false;
    }
  }
}

使用express-graphql进行发布


import { graphqlHTTP } from "express-graphql";
import { buildSchemaSync } from "type-graphql";

const app = express();
const schema = buildSchemaSync({
  resolvers: [RecipeResolver]
});

app.use("/graphql", graphqlHTTP({ schema: schema, graphiql: true }));

节点 + Express + GraphQL 订阅

生成客户端端代码

输出上述的模式。

const schema = buildSchemaSync({
  resolvers: [RecipeResolver]
});
const schema_str = printSchema(schema);
fs.writeFileSync("schema.graphql", schema_str);

创建文件

query getRecipe($id: String!) {
  recipe(id: $id) {
    id
    title
    description
    creationDate
    ingredients
  }
}

安装GraphQL代码生成器

以下是這次需要使用的插件,請先安裝好:
– typescript
– typescript-operations
– typescript-graphql-request

https://www.graphql-code-generator.com/docs/plugins/index

配置文件

schema: schema.graphql
documents: "documents/*.graphql"

generates:
  dist/client_sdk.ts:
    plugins:
      - typescript
      - typescript-operations
      - typescript-graphql-request

产生

客户端代码会被生成。
运行 npx graphql-codegen –config codegen.yml

在客户端获取数据

import { getSdk } from "client_sdk.ts";
const client = new GraphQLClient("/graphql");
const sdk = getSdk(client);
const recipe = await sdk.getRecipe('aaa')

书后的话

与Rest API相比,它确实更麻烦,但它提供了可靠的类型检查等功能,让人感到放心。
自动生成客户端SDK非常方便。
如果还能自动生成文档,那就完美了。