[REST API] JSON 데이터가공 처리과정

이재영·2024년 11월 6일

[ API ] : fatsecret Platform REST API (OAuth 1.0 Protocal)


데이터 반환 JSON 형식

해당 API의 응답 형식은 다음과 같다
JSON Example

{
  "foods": {
    "food": {
      "food_description": "Per 100g - Calories: 22kcal | Fat: 0.34g | Carbs: 3.28g | Protein: 3.09g",
      "food_id": "36421",
      "food_name": "Mushrooms",
      "food_type": "Generic",
      "food_url": "https://www.fatsecret.com/calories-nutrition/usda/mushrooms"
    },
    "max_results": "1",
    "page_number": "0",
    "total_results": "1129"
  }
}

위 JSON 형식의 문제점

반환된 JSON형식은 각 음식의 설명은 영양 정보가 포함된 문자열로 되어 있으며, 본인은 각 영양성분을 분리하여 개별적인 값으로 변환하는 것이 필요하였다...

해결법

문자열 파싱

description은 보다시피 “서빙 크기”와 “영양 정보”가 함께 포함되어 있다.

"1 medium apple - 95kcal | 0.3g fat | 25g carbs | 0.5g protein"

먼저 서빙 크기 부분은 " - "를 기준으로 분리하고, 나머지 영양 정보 부분은 " | "로 나누어 각 항목을 추출하였다.

파싱 코드

String servingUnit = description.split(' - ')[0].substring(4).trim();

List<String> parts = description.split(' - ')[1].split(' | ');

데이터 타입 변환

영양 정보를 얻은 후, 그 값들은 문자열로 제공되므로, 나중에 해당 데이터를 사용하려고 하면, 이를 number 타입으로 변환해야 한다. 예를 들어, 95kcal에서 95만을 추출하려면 문자열에서 kcal을 제거하고, 나머지 숫자를 정수로 변환해야 한다. 이와 유사하게 0.3g fat에서 0.3만을 추출하고, 이를 double 타입으로 변환하는 과정도 필요하였다.

foodNutritions.add(
        FoodNutrition(
          name: food['food_name'], // food_name 추가
          calories: int.parse(parts[0].split(': ')[1].replaceAll('kcal', '')),
          fat: double.parse(parts[1].split(': ')[1].replaceAll('g', '')).round(), // 정수형 변환
          carbs: double.parse(parts[2].split(': ')[1].replaceAll('g', '')).round(), // 정수형 변환
          protein: double.parse(parts[3].split(': ')[1].replaceAll('g', '')).round(), // 정수형 변환
          servingUnit: servingUnit,
        ),
      );


추가 문제점!

API 응답을 처리하는 중에 예상치 못한 키나 데이터 포맷의 차이로 에러가 발생했다. 예를 들어, 어떤 음식 항목에서는 food_description이 없거나 다른 형식으로 제공되어 예외가 발생했다. 이 문제는 null 체크와 데이터 포맷을 확인하는 코드를 추가함으로써 해결했다.

최종 응답 처리 코드

final Map<String, dynamic> jsonResponse = json.decode(response.body);
final List<dynamic> foodList = jsonResponse['foods']['food'];

List<FoodNutrition> foodNutritions = [];
    
for (var food in foodList) {
      String description = food['food_description'];

      // "Per" 뒤에 오는 서빙 양 추출
      String servingUnit = description.split(' - ')[0].substring(4).trim();

      List<String> parts = description.split(' - ')[1].split(' | ');

      foodNutritions.add(
        FoodNutrition(
          name: food['food_name'], // food_name 추가
          calories: int.parse(parts[0].split(': ')[1].replaceAll('kcal', '')),
          fat: double.parse(parts[1].split(': ')[1].replaceAll('g', '')).round(), // 정수형 변환
          carbs: double.parse(parts[2].split(': ')[1].replaceAll('g', '')).round(), // 정수형 변환
          protein: double.parse(parts[3].split(': ')[1].replaceAll('g', '')).round(), // 정수형 변환
          servingUnit: servingUnit,
        ),
      );
    }



https://platform.fatsecret.com/docs/v1/foods.search#json

profile
how to define. how to solve.

0개의 댓글