콘텐츠로 이동

2022 04 07

2022-04-07

Dovemetric (Airtable) Api 호출

  • 요청 URL

    • 되게 신기? 하게도 쿼리스트링에 바로 JSON 느낌나는 친구들을 한 바닥 넣어뒀음
      https://airtable.com/v0.3/application/apppcI0nClUwo3GCb/read
      ?stringifiedObjectParams={
          "includeDataForTableIds":["tbllShMbhc5jooPRb"],
          "includeDataForViewIds":["viwymTshkJuerbyeT"],
          "shouldIncludeSchemaChecksum":true
      }
      &requestId=reqwFpzEWYyla6C9a
      &accessPolicy={
          "allowedActions":[
              {"modelClassName":"application","modelIdSelector":"apppcI0nClUwo3GCb","action":"read"},
              {"modelClassName":"application","modelIdSelector":"apppcI0nClUwo3GCb","action":"readForDetailView"},
              {"modelClassName":"table","modelIdSelector":"apppcI0nClUwo3GCb *","action":"read"},
              {"modelClassName":"table","modelIdSelector":"apppcI0nClUwo3GCb *","action":"readData"},
              {"modelClassName":"table","modelIdSelector":"apppcI0nClUwo3GCb *","action":"readDataForRowCards"},
              {"modelClassName":"view","modelIdSelector":"apppcI0nClUwo3GCb *","action":"readRowOrder"},
              {"modelClassName":"view","modelIdSelector":"apppcI0nClUwo3GCb *","action":"readData"},
              {"modelClassName":"view","modelIdSelector":"apppcI0nClUwo3GCb *","action":"getMetadataForPrinting"},
              {"modelClassName":"row","modelIdSelector":"apppcI0nClUwo3GCb *","action":"readDataForDetailView"},
              {"modelClassName":"row","modelIdSelector":"apppcI0nClUwo3GCb *","action":"createBoxDocumentSession"},
              {"modelClassName":"row","modelIdSelector":"apppcI0nClUwo3GCb *","action":"createDocumentPreviewSession"}
          ],
          "shareId":"shrP7uEmnxbv7dUEV",
          "applicationId":"apppcI0nClUwo3GCb",
          "generationNumber":0,"expires":"2022-04-28T00:00:00.000Z",
          "signature":"efdff063ac6ebc4d0947704b43d9d2ee09b5a695f2900eb696dfee41e91364a6"
      }
      
    • 근데 여기에 airtable 에서 호출한 척 Header 까지 넣어줘야 401 Unauthorized를 벗어날 수 있음
      Host: airtable.com
      x-airtable-application-id: apppcI0nClUwo3GCb
      x-airtable-inter-service-client: webClient
      x-airtable-page-load-id: pglYshRJ38dSEq9iP
      x-early-prefetch: true
      X-Requested-With: XMLHttpRequest
      x-time-zone: Asia/Seoul
      x-user-locale: ko-KR
      
  • 최근 30일 Fundraising 으로 가보자!
    https://airtable.com/v0.3/view/viwjy9DFTjiMn0oY1/readData
    ?stringifiedObjectParams={}
    &requestId=reqVPJoQ3uIz7KUeT
    &accessPolicy={
        "allowedActions":[
            {"modelClassName":"application","modelIdSelector":"apppcI0nClUwo3GCb","action":"read"},
            {"modelClassName":"application","modelIdSelector":"apppcI0nClUwo3GCb","action":"readForDetailView"},
            {"modelClassName":"table","modelIdSelector":"apppcI0nClUwo3GCb *","action":"read"},
            {"modelClassName":"table","modelIdSelector":"apppcI0nClUwo3GCb *","action":"readData"},
            {"modelClassName":"table","modelIdSelector":"apppcI0nClUwo3GCb *","action":"readDataForRowCards"},
            {"modelClassName":"view","modelIdSelector":"apppcI0nClUwo3GCb *","action":"readRowOrder"},
            {"modelClassName":"view","modelIdSelector":"apppcI0nClUwo3GCb *","action":"readData"},
            {"modelClassName":"view","modelIdSelector":"apppcI0nClUwo3GCb *","action":"getMetadataForPrinting"},
            {"modelClassName":"row","modelIdSelector":"apppcI0nClUwo3GCb *","action":"readDataForDetailView"},
            {"modelClassName":"row","modelIdSelector":"apppcI0nClUwo3GCb *","action":"createBoxDocumentSession"},
            {"modelClassName":"row","modelIdSelector":"apppcI0nClUwo3GCb *","action":"createDocumentPreviewSession"}
        ],
        "shareId":"shrP7uEmnxbv7dUEV",
        "applicationId":"apppcI0nClUwo3GCb",
        "generationNumber":0,
        "expires":"2022-04-28T00:00:00.000Z",
        "signature":"efdff063ac6ebc4d0947704b43d9d2ee09b5a695f2900eb696dfee41e91364a6"
    }
    
  • Get 요청에 JSON을 쿼리 스트링으로 넘기네...?

JSON Parameter를 인코딩해서 넘겨주면 에러나!

  • 문제 상황

    • 처음에 JSON을 쿼리스트링으로 가진걸 Encoding 된 상태로 String 변수에 박아둠
      String url = "https://airtable.com/v0.3/application/apppcI0nClUwo3GCb/read?stringifiedObjectParams=%7B%22includeDataForTableIds%22%3A%5B%22tbllShMbhc5jooPRb%22%5D%2C%22includeDataForViewIds%22%3A%5B%22viwymTshkJuerbyeT%22%5D%2C%22shouldIncludeSchemaChecksum%22%3Atrue%7D&requestId=reqy9kjnQp9VdVlKF&accessPolicy=%7B%22allowedActions%22%3A%5B%7B%22modelClassName%22%3A%22application%22%2C%22modelIdSelector%22%3A%22apppcI0nClUwo3GCb%22%2C%22action%22%3A%22read%22%7D%2C%7B%22modelClassName%22%3A%22application%22%2C%22modelIdSelector%22%3A%22apppcI0nClUwo3GCb%22%2C%22action%22%3A%22readForDetailView%22%7D%2C%7B%22modelClassName%22%3A%22table%22%2C%22modelIdSelector%22%3A%22apppcI0nClUwo3GCb%20*%22%2C%22action%22%3A%22read%22%7D%2C%7B%22modelClassName%22%3A%22table%22%2C%22modelIdSelector%22%3A%22apppcI0nClUwo3GCb%20*%22%2C%22action%22%3A%22readData%22%7D%2C%7B%22modelClassName%22%3A%22table%22%2C%22modelIdSelector%22%3A%22apppcI0nClUwo3GCb%20*%22%2C%22action%22%3A%22readDataForRowCards%22%7D%2C%7B%22modelClassName%22%3A%22view%22%2C%22modelIdSelector%22%3A%22apppcI0nClUwo3GCb%20*%22%2C%22action%22%3A%22readRowOrder%22%7D%2C%7B%22modelClassName%22%3A%22view%22%2C%22modelIdSelector%22%3A%22apppcI0nClUwo3GCb%20*%22%2C%22action%22%3A%22readData%22%7D%2C%7B%22modelClassName%22%3A%22view%22%2C%22modelIdSelector%22%3A%22apppcI0nClUwo3GCb%20*%22%2C%22action%22%3A%22getMetadataForPrinting%22%7D%2C%7B%22modelClassName%22%3A%22row%22%2C%22modelIdSelector%22%3A%22apppcI0nClUwo3GCb%20*%22%2C%22action%22%3A%22readDataForDetailView%22%7D%2C%7B%22modelClassName%22%3A%22row%22%2C%22modelIdSelector%22%3A%22apppcI0nClUwo3GCb%20*%22%2C%22action%22%3A%22createBoxDocumentSession%22%7D%2C%7B%22modelClassName%22%3A%22row%22%2C%22modelIdSelector%22%3A%22apppcI0nClUwo3GCb%20*%22%2C%22action%22%3A%22createDocumentPreviewSession%22%7D%5D%2C%22shareId%22%3A%22shrP7uEmnxbv7dUEV%22%2C%22applicationId%22%3A%22apppcI0nClUwo3GCb%22%2C%22generationNumber%22%3A0%2C%22expires%22%3A%222022-04-28T00%3A00%3A00.000Z%22%2C%22signature%22%3A%22efdff063ac6ebc4d0947704b43d9d2ee09b5a695f2900eb696dfee41e91364a6%22%7D";
      
    • RestTemplate에 URL 그대로 넘기면 Encoding이 일어남
    • 이미 Encoding 된 String 값이 "또" Encoding이 일어남
    • 그러면 제대로 요청이 안보내짐
      • 이게 문제였는데 HttpHeader만 한 세시간 정도 지지고 볶았음...
  • 해결 방법

    • 여기에 UriComponentBuilder도 encode 옵션을 빼줘야해!
      • build()의 parameter에 false를 넣자
        UriComponents uriComponents = UriComponentsBuilder.fromHttpUrl(REQUEST_URL)
                .queryParam("stringifiedObjectParams", STRINGIFIED_OBJECT_PARAMS)
                .queryParam("requestId", REQUEST_ID)
                .queryParam("accessPolicy", ACCESS_POLICY)
                .build(false);
        uriString = uriComponents.toUriString();