2017-01-09 2 views
1

저는 Graph API를 내 일부 REST API 대신 사용하여 찾고 있었고, 기본을 중심으로 내 머리를 감싸고 지금까지 보았던 대부분을 좋아한다고 생각합니다. 한 가지 중요한 기능이 빠져있는 것 같습니다.GraphQL 응답의 사용자 정의 맵 키

의 내가 같은 항목의 컬렉션을 가지고 있다고 가정 해 봅시다 :

응용 프로그램과 같은 ID에 의해 색인 모든 개체의지도를 필요로

{ 
    "id": "aaa", 
    "name": "Item 1", 
    ... 
} 
:

{ 
    "allItems": { 
     "aaa": { 
      "name": "Item 1", 
      ... 
     }, 
     "aab": { 
      "name": "Item 2", 
      ... 
     } 
    } 
} 

모든 API의 I를 필자는이 같은 형식으로 결과를 되돌릴 수 있었지만 GraphQL을 사용하여 결과를 얻으려고 애쓰는 중입니다. issue 101을 계속해서 실행하지만 알 수없는 스키마가 더 많습니다. 제 경우에는 모든 분야가 정확히 무엇인지 압니다. 이것은 순전히 출력 형식에 관한 것입니다. 나는 단순히 배열의 모든 항목을 반환하고 클라이언트 쪽을 다시 포맷 할 수 있지만, 과거에는 절대로 필요하지 않다는 점을 감안할 때 지나치게 과장된 것처럼 보였습니다. GraphQL은 한 걸음 뒤로 물러 설 것입니다. 내가하려는 일이 불가능하거나 모든 잘못된 용어를 사용하고 있는지 확실하지 않습니다. 나는 계속 파고 야합니까, 아니면 내 요구에 맞지 않는 GraphQL입니까? 이것이 가능하다면 이런 식으로 데이터를 검색하는 쿼리는 어떻게 생겼을까요?

저는 서버에서 graphql-php으로 현재 작업하고 있습니다. 그러나 더 높은 수준의 개념적 응답에 대해 열려 있습니다.

+0

"GraphQL을 뒤로 물러나게 만들 것입니다."- 귀하의 경우에는 웹 서비스의 모든 클라이언트가 무엇을 필요로하는지 알 것입니다. 그렇지 않으면지도가 클라이언트가 필요로한다는 가정을하고 있습니다. 웹 서비스가 반환하는 것과 반대되는 것이 필요한 클라이언트는 일종의 변환을 수행해야합니다. IMHO,지도 또는 배열 스타일 컬렉션을 반환할지 여부는 클라이언트가 원하는 것인지 50:50인지 여부에 따라 결정됩니다. – CommonsWare

+0

@CommonsWare 내가 지금 염두에두고있는 API는 조직 내부에서만 사용되므로 예, 모든 클라이언트가 항상 데이터를 가져 오는 형식으로 데이터를 필요로한다고 말할 수 있습니다. 페이지로드를 로컬 검색을위한 빠른 색인으로 사용하고 확장 된 항목 정보를 필요한만큼 (GraphQL에서 쉽게 표현할 수있는 형식으로) 검색합니다.문제는 단순히 내가하려는 일이 가능한지 여부입니다. –

+0

"모든 클라이언트는 항상 가져온 형식으로 데이터를 필요로합니다"- 컬렉션을지도로 변환하는 것은 대부분의 현대 프로그래밍 언어에서 1-3 줄의 코드를 필요로합니다. "GraphQL은 내 요구에 적합하지 않습니까?" - 웹 서비스에서 특정 JSON 구조를 반환하도록 요구하는 경우 GraphQL이 적합하지 않습니다. 이 경우를 지나서도 (그리고 나는 해결책을 모른다), 당신은 다른 것을 치게 될 것입니다. 스키마에 의해 지시되는 JSON의 구조를 절대적으로 제어 할 수 없으며 스키마는 임의의 구조를 처리하도록 설계되지 않았습니다. – CommonsWare

답변

5

불행히도 이처럼 임의의 동적 키를 가진 객체를 반환하는 것은 실제로 GraphQL의 일류 시민은 아닙니다. 그것은 당신이 똑같은 것을 달성 할 수 없다는 것을 말하는 것은 아니지만 그렇게함으로써 GraphQL의 많은 이점을 잃을 것입니다.

ID가 포함 된 개체의 컬렉션/목록을 반환하는 대신 id 키를 사용하여 개체를 반환 할 때 설정 한 다음 클라이언트에서 변환을 수행하면 특수 GraphQLScalarType을 만들 수 있습니다.

const GraphQLAnyObject = new GraphQLScalarType({ 
    name: 'AnyObject', 
    description: 'Any JSON object. This type bypasses type checking.', 
    serialize: value => { 
    return value; 
    }, 
    parseValue: value => { 
    return value; 
    }, 
    parseLiteral: ast => { 
    if (ast.kind !== Kind.OBJECT) { 
     throw new GraphQLError("Query error: Can only parse object but got a: " + ast.kind, [ast]); 
    } 
    return ast.value; 
    } 
}); 

이 접근법의 문제점은 스칼라 유형이므로 쿼리 할 수있는 선택 세트를 제공 할 수 없다는 것입니다. E.G. 당신이 그런 유형

type MyType implements Node { 
    id: ID! 
    myKeyedCollection: AnyObject 
} 

이 있다면 당신은 단지 지금처럼 쿼리 할 수있을 것

query { 
    getMyType(id: abc) { 
    myKeyedCollection # note there is no { ... } 
    } 
} 

다른 사람이 말했듯이 당신이 혜택을 많이 잃어 가고 있기 때문에,이 권하고 싶지 않다 GraphQL은 여전히 ​​REST가 할 수있는 모든 것을 할 수 있다는 것을 보여줍니다. 사용해보고 싶다면 scaphold.io에 AnyObject 유형을 제공하고 주위에서 놀 수 있습니다.

희망이 도움이됩니다.