-
graphql 데이터 api만들고 연동 , 타입관 관계형성하기개발 2020. 2. 11. 20:06
api를 만들기 위해서 json-server사용한다.
fake db를 만들어보자
db.json
{ "Users":[ { "id":"1","firstName":"Hwi","age":31 }, { "id":"2","firstName":"Yunji","age":25 } ] }
이후 package.json 에서
"scripts": { "test": "echo \"Error: no test specified\" && exit 1", "json:server":"json-server --watch db.json" },
해당 json:server 스크립트를 넣어주고
두번째 터미널을 열어 (server돌아가는중) npm run json:server를 실행한다.
이와같이 3000포트로 api 를 만들수있다. /Users/1 이렇게 id 로도 접근할수있다.
const RootQuery = new GraphQLObjectType({ name:'RootQueryType', fields:{ user:{ type:UserType, args:{id:{type:GraphQLString}}, resolve(parentValue,args){ return axios.get(`http://localhost:3000/users/${args.id}`) .then(res=>{ console.log(res); return res.data; }) } } } })
지난번 만들었던 RootQuery 에서 resolve 함수를 바꿔보자
axios 를 통해 api에 접근해서 데이터를 리턴하면 된다.
만약 두개의 데이터 타입이있고 두개가 연관이있다면 어떻게 스키마를 정의해야할까
예로 user가있고 그들이 일하는 companies 가있다고 해보자
먼저 CompanyType을 만든다
const CompanyType = new GraphQLObjectType({ name:'Company', firstName:{ id:{type:GraphQLString}, name:{type:GraphQLString}, description:{type:GraphQLString} } })
그리고 user에 companyType 필드를 넣어주자
const UserType = new GraphQLObjectType({ name:'User', fields:{ id:{type:GraphQLString}, firstName:{type:GraphQLString}, age:{type:GraphQLInt}, company:{type:CompanyType} } })
하지만 실 데이터를 보면 user 데이터에서는 companyId 만 제공하고있다.
해당 companyId 를 통해 company의 정보를 가져와 User를 쿼리할때 보여주려한다.
{ "users":[ { "id":"1","firstName":"Hwi","age":31,"companyId":11 }, { "id":"2","firstName":"Yunji","age":25,"companyId":22 } ], "companies":[ {"id":"11","name":"apple","description":"iphone"}, {"id":"22","name":"samsung","description":"galaxy"} ] }
우선 companyId를 불러와보자
resolve함수에서 제공되는 parentValue 를 콘솔에 찍어보면
company:{ type:CompanyType, resolve(parentValue,args){ console.log(parentValue); } }
이렇게 해당 User의 정보를 한번에 얻을수있다.
parentValue.companyId 를 http 리퀘스트에 사용하면 원하는 정보를 얻어 company필드에 적용하면된다.
const UserType = new GraphQLObjectType({ name:'User', fields:{ id:{type:GraphQLString}, firstName:{type:GraphQLString}, age:{type:GraphQLInt}, company:{ type:CompanyType, resolve(parentValue,args){ console.log(parentValue); return axios.get(`http://localhost:3000/companies/${parentValue.companyId}`) .then((res)=>res.data); } } } })
이렇게 쿼리가 가능해진다. user 말고 company 자체를 쿼리하고 싶다면 Rootquery에 필드 추가하면된다.
const RootQuery = new GraphQLObjectType({ name:'RootQueryType', fields:{ user:{ type:UserType, args:{id:{type:GraphQLString}}, resolve(parentValue,args){ return axios.get(`http://localhost:3000/users/${args.id}`) .then(res=>{ console.log(res); return res.data; }) } }, company:{ type:CompanyType, args:{id:{type:GraphQLString}}, resolve(parentValue,args){ return axios.get(`http://localhost:3000/companies/${args.id}`) .then(res=>{ return res.data; }) } } } })
이번에는 company 쿼리를 통해 해당 회사에 소속되어있는 users 를 불러올것이다.
const CompanyType = new GraphQLObjectType({ name:'Company', fields:{ id:{type:GraphQLString}, name:{type:GraphQLString}, description:{type:GraphQLString}, user:{ type: new GraphQLList(UserType), resolve(parentValue,args){ console.log(parentValue); return axios.get(`http://localhost:3000/companies/${parentValue.id}/users`); } } } })
field에 user를 추가하고 원하는 데이터가있는 url 을 추가했다. (parentValue .id 에는 해당 회사의 id가 들어있다)
여러 user를 데려올거기 때문에 GraphQLList 타입을 사용했다.
하지만 참조하고있는 userType 이 (코드가) 그 아래에 선언되었기떄문에 에러가 발생한다.
이는 화살표함수로 해결가능하다 ( 다 선언된 후에 함수가 실행됨)
const CompanyType = new GraphQLObjectType({ name:'Company', fields:()=>({ id:{type:GraphQLString}, name:{type:GraphQLString}, description:{type:GraphQLString}, user:{ type: new GraphQLList(UserType), resolve(parentValue,args){ console.log(parentValue.id); return axios.get(`http://localhost:3000/companies/${parentValue.id}/users`) .then((res)=>res.data); } } }) })
'개발' 카테고리의 다른 글
graphql+react 변수를 가지고 Mutation 실행하기 (0) 2020.02.26 mongoDB 셋업하기 (0) 2020.02.18 GraphQL Mutation 스키마 만들어 delete,edit 해보기 (0) 2020.02.12 graphql 시작하기 (0) 2020.01.28 react firebase 연동 auth 정보 db, app에 저장하기 (0) 2020.01.07