ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 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);
                }
            }
        })  
    })

     

     

    댓글

Designed by Tistory.