apollo-server - Graphql Api Chuck Norris
问题描述
我需要帮助构建一个包装 ChuckNorris.io API 的 GraphQL Api
API 应该具有解析所有类别的查询类型(https://api.chuckmorris.io/jokes/categories)
Api 应该具有 Query 类型,可以解决作为参数给出的随机笑话 ( https://api.chucknorris.io/jokes/random?category= {category})
const express=require('express');
const {ApolloServer,gql}=require('apollo-server-express');
const fetch=require('node-fetch');
const typeDefs=gql`
type Joke{
icon_url:String,
id:String,
url:String
value: String
}
type Category{
animal:String
career:String
celebrity:String
dev:String
explicit:String
fashion:String
food:String
history:String
money:String
movie:String
music:String
political:Strig
religion:String
science:String
sport:String
travel:String
}
type Query{
getCategory(category:String!):Joke
category:Category
}
`
const resolvers={
Query:{
getCategory: async(_,{category})=>{
const response=await fetch(`https://api.chucknorris.io/jokes/random?category=${category}`)
return response.json();
},
category: async(_,{})=>{
const response=await fetch('https://api.chucknorris.io/jokes/categories')
return response.json();
}
}
}
const server= new ApolloServer({typeDefs,resolvers});
const app=express();
server.applyMiddleware({app});
app.listen({port:4000},()=>
console.log('Now browse to http://localhost:4000' + server.graphqlPath)
)
解决方案
您对类型类别的查询应该返回一个字符串列表(数组),所以
export const typeDefs = gql`
type Joke {
value: String!
id:ID!
icon_url:String!
}
type Query {
getAllCategories:[String!]!
randomJoke(category: String!):Joke
}
`;
对于您的解析器,您不需要获取。apollo 提供数据源来连接到外部 REST API,就像您拥有的那样。所以安装 npm 包“apollo-datasource-rest”并将其添加到您的 apollo 服务器实例中,如下所示
const server = new ApolloServer({
typeDefs,
resolvers,
dataSources: ()=>({
jokeinstance : new Jokenorris
})
})
然后为 Jokenorris 创建数据源类并正确导入或像您一样在一个 src 文件中执行所有操作。
import pkg from "apollo-datasource-rest";
const { RESTDataSource } = pkg;
export class Jokenorris extends RESTDataSource {
constructor() {
super();
this.baseURL = "https://api.chucknorris.io/jokes";
}
async getAllCategories() {
const res = await this.get("categories");
return res;
}
async getRandomJoke({ category }) {
const response = await this.get("random", { category: category });
return response;
}
}
那么您的解析器可能看起来像这样,如果您将所有内容分块在一个文件中,您可以忽略导出和导入
export const resolvers = {
Query: {
allJokeCategories: (_, __, { dataSources }) =>
dataSources.jokeinstance.getAllCategories(),
randomJoke: (_, {category}, {dataSources})=>
dataSources.jokeinstance.getRandomJoke({category:category})
},
};
推荐阅读
- ios - 我可以使用相同的上下文在 coredata 中保存两个实体吗?
- bash - 无法在我的 docker 容器中启动脚本
- angularjs - 如何将 JSON 和图像文件发送到服务器?
- javascript - (节点:31260)UnhandledPromiseRejectionWarning
- laravel - Laravel Image 干预在上传时出现 503 错误
- java - Android RecyclerView:如果不使用“setIsRecyclabe(false)”,则滚动期间内存使用量会增加
- swift - 从 Swift 中的字符串中删除 '
- python - Python:将开始日期和结束日期拆分为开始日期和结束日期之间的所有日期
- javascript - Rxjs 在继续之前等待先前的间隔请求执行
- python - Python中两个矩阵的并集