Apollo-link-rest: ์„œ๋ฒ„๊ฐ€ ๋น„-graphql ํ˜ธํ™˜ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ•˜๋‚˜์š”?

์— ๋งŒ๋“  2018๋…„ 06์›” 20์ผ  ยท  6์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: apollographql/apollo-link-rest

๋‚ด๊ฐ€ํ•˜๋ ค๋Š” ๊ฒƒ์€ http ๋‚˜๋จธ์ง€ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ†ตํ•ด bcoin์— ๊ณ„์ • ์ •๋ณด๋ฅผ ์ฟผ๋ฆฌํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
๊ทธ๋ ‡๊ฒŒ ํ•˜๋ ค๋ฉด

  1. ๋ชจ๋“  ๊ธฐ์กด์˜ ์ด๋ฆ„์„ ๋ฌผ์–ด accountName ํ˜ธ์ถœํ•˜์—ฌ GET /wallet/:id/account
  2. GET /wallet/:id/account/:accountName ๊ณ„์ • ์„ธ๋ถ€ ์ •๋ณด๋ฅผ ์š”์ฒญํ•˜์‹ญ์‹œ์˜ค.

๋ฌธ์ œ๋Š” ์ฒซ ๋ฒˆ์งธ ํ˜ธ์ถœ์ด ["default", "mySecondAccountName"] ์™€ ๊ฐ™์€ ๊ฒƒ์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
graphql ์‘๋‹ต์œผ๋กœ ๊ตฌ๋ฌธ ๋ถ„์„ํ•˜๊ฑฐ๋‚˜ ๋‘ ๋ฒˆ์งธ GET ์ง์ ‘ ์ „๋‹ฌํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ชจ๋ฆ…๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด ๋‹ค์Œ ์ฟผ๋ฆฌ๋กœ ์ฟผ๋ฆฌ๋ฅผ ์‹œ๋„ํ–ˆ์„ ๋•Œ,

query (id: "primary") @rest(type: AccountName, path: "/wallet/:id/account") {
  default

๋‚˜๋Š” Error: Network error: Cannot create property 'default' on string 'default' ๋ฐ›์„ ๊ฒƒ์ด๋‹ค

๋ฌธ์„œ์—์„œ ๋‹จ์„œ๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†์—ˆ์ง€๋งŒ ์ด๊ฒƒ์€ ๋งค์šฐ ์ผ๋ฐ˜์ ์ธ ๊ฒฝ์šฐ์ธ ๊ฒƒ ๊ฐ™์•„์„œ ๋งค์šฐ ๊ฐ„๋‹จํ•œ ๊ฒƒ์„ ๋†“์น˜๊ณ  ์žˆ๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๋ˆ„๊ตฐ๊ฐ€ ๋‚ด๊ฐ€ ์ฐพ์•„์•ผ ํ•  ๊ฒƒ์„ ์ง€์ ํ•ด ์ฃผ์‹œ๋ฉด ์ •๋ง ๊ฐ์‚ฌํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

questionโ”

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

๋‚œ ๋‹น์‹ ์ด ์‚ฌ์šฉํ•œ๋‹ค๊ณ  ์ƒ๊ฐ @joemphilips typePatcher์„

๋‚˜๋Š” ๊ทธ๊ฒƒ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋น„ graphql ํ˜ธํ™˜ ์‘๋‹ต์„ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

{
   "100": {
      "id": 100,
      "node_id": 105,
      "category_id": 8,
      "title": "Title 100",
      "highlight": true
   },
   "138": {
      "id": 138,
      "node_id": 106,
      "category_id": 7,
      "title": "Title 138",
      "highlight": false
   },
   "140": {
      "id": 140,
      "node_id": 101,
      "category_id": 9,
      "title": "Title 140",
      "highlight": false
   },
   "158": {
      "id": 158,
      "node_id": 146,
      "category_id": 4,
      "title": "Title 158",
      "highlight": false
   }
}

์ฟผ๋ฆฌ ์ •์˜

import { gql } from 'apollo-boost';

export const GET_NEWS_QUERY = gql`
  query getNews {
    News @rest(type: "News", path: "news") {
      data
    }
  }
`;

RestLink ๊ตฌ์„ฑ

const restLink = new RestLink({
  uri: API_URL,
  typePatcher: {
    News: (data, outerType) => {
      if (outerType === 'News') {
        data = Object.keys(data).map(id => {
          const result = data[id];

          if (result) {
            return {
              __typename: 'News',
              ...result
            };
          }
        });
      }

      return { data };
    }
  }
});

์ฟผ๋ฆฌ ์‚ฌ์šฉ
```js
๋ Œ๋”๋ง() {
๋ฐ˜ํ’ˆ (
{({ ๋กœ๋”ฉ, ์˜ค๋ฅ˜, ๋ฐ์ดํ„ฐ }) => {
if (๋กœ๋”ฉ) {
๋ฐ˜ํ’ˆ (

๋กœ๋“œ ์ค‘...

);
}

      if (error) {
        return (
          <View>
            <Text>Error :(</Text>
          </View>
        );
      }

      const news = data && data.News && data.News.data;
      const filteredNews = news && news.filter(Boolean);

      return (
        <Styles.Container>
          <Carousel
            data={filteredNews}
            handleOnPress={this.navigateToScreen}
          />
        </Styles.Container>
      );
    }}
  </Query>
);

}
`
``

๋ชจ๋“  6 ๋Œ“๊ธ€

๋‚˜๋Š” bcoin์— ์ต์ˆ™ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ์ถ”์ธกํ•˜๊ณ  ์žˆ์ง€๋งŒ ์—ฌ๊ธฐ์— ์ œ์•ˆ ์‚ฌํ•ญ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

query Account(id: $id){
   account(id: $id) @rest(type: "[String]", path: "/wallet/:id/account")
}

๊ทธ๋Ÿฐ ๋‹ค์Œ ๋ฐ์ดํ„ฐ์—์„œ ๊ฒฐ๊ณผ๋ฅผ ๊ฐ€์ ธ์™€ ๊ณ„์ • ์„ธ๋ถ€ ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ์ƒˆ ์ฟผ๋ฆฌ์— ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.

์นœ์ ˆํ•˜๊ณ  ๋น ๋ฅธ ๋‹ต๋ณ€ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. @fbartho
์•„๋งˆ๋„ ๋‚ด๊ฐ€ bcoin์— ๋Œ€ํ•ด ์–ธ๊ธ‰ํ•˜์ง€ ๋ง์•˜์–ด์•ผ ํ–ˆ๋Š”๋ฐ, ๋‚ด ๋ฌธ์ œ๋Š” ๋” ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค

๋ฌธ์„œ์˜ @export ์ง€์‹œ๋ฌธ ์˜ˆ์ œ์—๋Š” REST ๋์ ์„ ๋‘ ๋ฒˆ ํ˜ธ์ถœํ•˜๋Š” ์˜ˆ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.
์ œ ์งˆ๋ฌธ์€ ์ด ์˜ˆ์ œ์˜ ์ฒซ ๋ฒˆ์งธ ์ฟผ๋ฆฌ๊ฐ€ ๊ฐ์ฒด ๋ฐฐ์—ด ๋Œ€์‹  ์Šค์นผ๋ผ ๋ฐฐ์—ด์„ ๋ฐ˜ํ™˜ํ•  ๋•Œ ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ•ฉ๋‹ˆ๊นŒ?
ํ‚ค๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์— ๋‚ด๋ณด๋‚ผ ์ธ์ˆ˜๋ฅผ ์ง€์ •ํ•  ๋ฐฉ๋ฒ•์ด ์—†๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

๋˜ํ•œ @export ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ๋Œ€์‹  ์–ธ๊ธ‰ํ•œ ๋Œ€๋กœ ์ฟผ๋ฆฌ๋ฅผ ์‹œ๋„ํ–ˆ์ง€๋งŒ ๊ฐ€์ ธ์˜ค๊ธฐ ๊ฒฐ๊ณผ๋Š” {}
๋‹ค์Œ ๊ฒฝ๊ณ ์™€ ํ•จ๊ป˜

Missing field account in {}

๊ทธ๊ฑด ๊ทธ๋ ‡๊ณ , ๋‚˜๋Š” ๋‹น์‹ ์˜ ์ œ์•ˆ์—์„œ ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค

query Account(id: $id)

ํ•ด์•ผํ•œ๋‹ค

query Account($id: id)

๋‚˜๋Š” ๋‹น์‹ ์ด ์ œ์•ˆํ•œ ๋ช…๋ น์„ ์‹คํ–‰ํ•  ๋•Œ, ์ฆ‰

query Account(id: $id){
   account(id: $id) @rest(type: "[String]", path: "/wallet/:id/account")
}

์‹ค์ œ๋กœ ์ฟผ๋ฆฌ๋ฅผ ์‹คํ–‰ํ•˜์ง€ ์•Š๊ณ  {} ๋ฅผ data ๋กœ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
๋‚ด๊ฐ€ ์ง€์ •ํ•ด์•ผํ•˜๋ฏ€๋กœ { theFieldNameIDesire } ์˜ ์„  ํ›„ account , ๋ฌธ์ œ๋Š” ๋‚ด๊ฐ€ ์ง€์ •ํ•˜๋Š” ํ•„๋“œ ์ด๋ฆ„์ด ์—†๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค :(

๋‚œ ๋‹น์‹ ์ด ์‚ฌ์šฉํ•œ๋‹ค๊ณ  ์ƒ๊ฐ @joemphilips typePatcher์„

๋‚˜๋Š” ๊ทธ๊ฒƒ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋น„ graphql ํ˜ธํ™˜ ์‘๋‹ต์„ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

{
   "100": {
      "id": 100,
      "node_id": 105,
      "category_id": 8,
      "title": "Title 100",
      "highlight": true
   },
   "138": {
      "id": 138,
      "node_id": 106,
      "category_id": 7,
      "title": "Title 138",
      "highlight": false
   },
   "140": {
      "id": 140,
      "node_id": 101,
      "category_id": 9,
      "title": "Title 140",
      "highlight": false
   },
   "158": {
      "id": 158,
      "node_id": 146,
      "category_id": 4,
      "title": "Title 158",
      "highlight": false
   }
}

์ฟผ๋ฆฌ ์ •์˜

import { gql } from 'apollo-boost';

export const GET_NEWS_QUERY = gql`
  query getNews {
    News @rest(type: "News", path: "news") {
      data
    }
  }
`;

RestLink ๊ตฌ์„ฑ

const restLink = new RestLink({
  uri: API_URL,
  typePatcher: {
    News: (data, outerType) => {
      if (outerType === 'News') {
        data = Object.keys(data).map(id => {
          const result = data[id];

          if (result) {
            return {
              __typename: 'News',
              ...result
            };
          }
        });
      }

      return { data };
    }
  }
});

์ฟผ๋ฆฌ ์‚ฌ์šฉ
```js
๋ Œ๋”๋ง() {
๋ฐ˜ํ’ˆ (
{({ ๋กœ๋”ฉ, ์˜ค๋ฅ˜, ๋ฐ์ดํ„ฐ }) => {
if (๋กœ๋”ฉ) {
๋ฐ˜ํ’ˆ (

๋กœ๋“œ ์ค‘...

);
}

      if (error) {
        return (
          <View>
            <Text>Error :(</Text>
          </View>
        );
      }

      const news = data && data.News && data.News.data;
      const filteredNews = news && news.filter(Boolean);

      return (
        <Styles.Container>
          <Carousel
            data={filteredNews}
            handleOnPress={this.navigateToScreen}
          />
        </Styles.Container>
      );
    }}
  </Query>
);

}
`
``

๋‹ต๋ณ€์ด ๋Šฆ์–ด ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค. ๊ท€ํ•˜์˜ ์†”๋ฃจ์…˜์€ ๋ฐฐ์—ด์˜ ๋ฌธ์ž์—ด/์Šค์นผ๋ผ์— ๋Œ€ํ•ด ์ž‘๋™ํ•˜์ง€ ์•Š๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ํ•ด๊ฒฐ๋œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค . ๋‹ค์‹œ ํ•œ๋ฒˆ ์‹œ๋„ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ๋ฌธ์ œ๊ฐ€ ๊ณ„์†๋˜๋ฉด ๋‹ค์‹œ ์—ด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ์‚ฌ ํ•ด์š”.

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰