FatSecret Food Database REST API Client with Typescript

Have you ever wondered, how to provide your product a rich food and meals database? When we decided to have food search functionality in one of our products, Suguard (diabetes diary app, under development in React Native with Firebase and Typescript), we had to do some research on what service would suit our needs best. We needed something that is free for the most basic functionalities to validate our product with users. After some research, we realized, that FatSecret might be the best choice if we want to use 100% free service (the most basic pricing tier) for now. It might not suit all your needs, but we never claim that it is the best service of all. Some facts about FatSecret from their homepage:

The #1 food and nutrition database in the world, utilized by more than 10,000 developers, in more than 50 countries contributing in excess of 500 million API calls every month.

Authentication

To use FatSecret API you need to register as a developer here. The API uses authentication based on OAuth Core 1.0 protocol for securely signing all requests. Although documentation on FatSecret’s page looks rich, it takes some time to go through it. Here’s why this tutorial article comes by. Even though the code below is written in Typescript, it can easily be adjusted to Javascript so don’t worry if Typescript is not your thing. We use async functions which is an ES2017 feature, so it might be worth reading a bit about them.

Full API documentation can be found at Fatsecret Platform API docs.

What you need before start

As mentioned before, you will need a Fatsecret Developer account. You will need it to get Access Token also known as REST API Consumer Key and Access Secret sometimes referred to as REST API Shared Secret. From the documentation:

Access Token: A value which identifies a user of your application (you use the REST API Profile Management methods to generate these).

Access Secret: A secret we issue with the Access Token which helps us establish that you can perform a request on behalf of the user identified by the Access Token (you use the REST API Profile Management methods to generate these and/or retrieve these for your users).

Both OATH_VERSION and OAUTH_SIGNATURE_METHOD cannot be changed. We could have it hardcoded in our requests, but having it as const at the top of the file will make the code easier to understand and maintain.

To properly sign a request according to FatSecret documentation, we need to add appropriate HTTP query parameters to it. In this tutorial, we will cover only Signed Requests. As long as you don’t need any data specific to the user (like getting user’s weight history directly from FatSecret), you will not need Delegated Requests. More information about these two kinds of request can be found in the documentation.

Signature Base String

We need to generate Signature Base String by concatenating the HTTP method (GET or POST), the request URL and our query params in the following format:

<HTTP Method>&<Request URL>&<Normalized Parameters>

Request URL is simply API_PATH.

Query Params aka Normalized Parameters

Each method (like foods.search or food.get) in FatSecret REST API has it’s own set of supported params, but all of them share common OAuth parameters. Let’s create a helper function to get all of them.

We use constant values defined before. The only thing that might be unclear here is oauth_nonce which is a randomly generated string for a request that has been created from the timestamp and a random value.

We need to convert a plain Javascript object from getOauthParameters to a query string. For that, we will use the popular query-string library.

 yarn add query-string 
 yarn add --dev @types/query-string

Second-line will add optional Typescript definitions to the library (it is not included in the lib).

Now, let’s prepare a function to get the request signature.

We concatenate HTTP method, API Path (Request URL), and query params (Normalized Parameters) into a single string.

encodeURIComponent allows us to encode strings to be proper URIs, without unsafe characters (like ?=/&). You don’t need it to install or import it. It is part of Javascript standard built-in objects, available even in Internet Explorer 5.5.

hmcsha1 function comes from an external library, which must be added to package.json:

 yarn add hmacsha1

and imported in the source code:

 import hmacsha1 from 'hmacsha1';

If you don’t want to add external requirement to your project’s package.json, you can define hmacsha1 function in your source code as a one-liner.

API Call wrapper

We are almost there! All we need now is to call the FatSecret API.

methodParams is an object of method-specific query parameters. It will be a different set of properties for food search and different for other methods.

After computing the signature, we add oauth_signature to queryParams .

As you can see, we used the fetch library to interact with the API. You can use any HTTP client you want (axios for example).

Search method

In this tutorial, we will cover only one method, foods.search which seems to be entry point for further development. Other methods are very similar and our code can be reused for them.

query is our search expression. If we want to search for hamburgers, it will be hamburger. This one will probably come from input component. maxResults is a number value, which does not need much explanation.

Fetch returns a Promise so we need to await it’s results. At the end, we return response.json() from our function, which is Promise, that need to be used in our result displaying component. As you can see, we defined FatsecretResponse interface as result of our function. You can make it return Response , but you will not have type checks, which Typescript provides.

 export interface FatsecretFood { 
 food_id: string; 
 food_name: string; 
 food_type: FatsecretFoodType; 
 food_url: string; 
 brand_name?: string; 
 food_description: string; 
 }
 export enum FatsecretFoodType { 
 Brand = 'Brand', 
 Generic = 'Generic', 
 }
 export interface FatsecretResponse { 
 foods: { 
 food: FatsecretFood[]; 
 max_results: number; 
 total_results: number; 
 page_number: number; 
 }; 
 }

Full example

That’s it! You can execute API calls to FatSecret. In case you missed something, here’s a full example with an extra method to get single food data (by food ID).


FatSecret Food Database REST API Client with Typescript was originally published in DLabs.AI on Medium, where people are continuing the conversation by highlighting and responding to this story.

how to implement ai

Read more on our blog