Back

Step by Step Guide to Building a Harvest API Integration in C#

Aug 15, 20246 minute read

Introduction

Hey there, fellow developer! Ready to dive into the world of Harvest API integration? You're in for a treat. Harvest's API is a powerhouse for time tracking and project management, and we're about to harness that power in C#. Buckle up!

Prerequisites

Before we jump in, make sure you've got:

  • Visual Studio or your favorite C# IDE
  • .NET Core 3.1 or later
  • A Harvest account with API credentials (you've got this, right?)

Setting up the project

Let's kick things off:

  1. Fire up Visual Studio and create a new C# console application.
  2. Time to beef up our project. Open that Package Manager Console and run:
Install-Package Newtonsoft.Json
Install-Package RestSharp

These bad boys will make our lives easier when dealing with JSON and HTTP requests.

Authentication

Alright, authentication time! Harvest uses OAuth 2.0, but for simplicity, we'll use personal access tokens.

  1. Head to your Harvest account settings and generate a personal access token.
  2. Now, let's set up our API client:
var client = new RestClient("https://api.harvestapp.com/v2/"); client.AddDefaultHeader("Authorization", "Bearer YOUR_ACCESS_TOKEN"); client.AddDefaultHeader("Harvest-Account-Id", "YOUR_ACCOUNT_ID");

Making API requests

Time to make our first request! Let's fetch some time entries:

var request = new RestRequest("time_entries", Method.GET); var response = client.Execute(request); if (response.IsSuccessful) { var timeEntries = JsonConvert.DeserializeObject<TimeEntriesResponse>(response.Content); // Do something awesome with your time entries } else { Console.WriteLine($"Error: {response.ErrorMessage}"); }

Core API functionalities

Now that we're rolling, let's cover the CRUD operations:

Create a time entry

var newEntry = new RestRequest("time_entries", Method.POST); newEntry.AddJsonBody(new { project_id = 12345, task_id = 67890, spent_date = DateTime.Today.ToString("yyyy-MM-dd"), hours = 2.5 }); var createResponse = client.Execute(newEntry);

Update a time entry

var updateEntry = new RestRequest($"time_entries/{entryId}", Method.PATCH); updateEntry.AddJsonBody(new { hours = 3.0 }); var updateResponse = client.Execute(updateEntry);

Delete a time entry

var deleteEntry = new RestRequest($"time_entries/{entryId}", Method.DELETE); var deleteResponse = client.Execute(deleteEntry);

Advanced features

Pagination

Harvest uses cursor-based pagination. Here's how to handle it:

var request = new RestRequest("time_entries", Method.GET); request.AddQueryParameter("page", "1"); request.AddQueryParameter("per_page", "100"); var response = client.Execute(request); var data = JsonConvert.DeserializeObject<TimeEntriesResponse>(response.Content); while (!string.IsNullOrEmpty(data.Links.Next)) { request.Resource = data.Links.Next; response = client.Execute(request); data = JsonConvert.DeserializeObject<TimeEntriesResponse>(response.Content); // Process the data }

Filtering and sorting

Want to get fancy? Try this:

request.AddQueryParameter("from", "2023-01-01"); request.AddQueryParameter("to", "2023-12-31"); request.AddQueryParameter("project_id", "12345"); request.AddQueryParameter("sort", "spent_date:desc");

Error handling and logging

Don't forget to wrap your API calls in try-catch blocks and log the responses:

try { var response = client.Execute(request); Log.Information($"API Response: {response.Content}"); // Process the response } catch (Exception ex) { Log.Error($"API Error: {ex.Message}"); }

Testing the integration

Unit testing is your friend. Here's a quick example using xUnit:

[Fact] public void TestGetTimeEntries() { var client = new HarvestClient("YOUR_ACCESS_TOKEN", "YOUR_ACCOUNT_ID"); var entries = client.GetTimeEntries(); Assert.NotNull(entries); Assert.True(entries.Count > 0); }

Best practices and optimization

  • Respect Harvest's rate limits (100 requests per 15 seconds per account).
  • Cache frequently accessed data to reduce API calls.
  • Use asynchronous methods for better performance in web applications.

Conclusion

And there you have it! You're now equipped to build a robust Harvest API integration in C#. Remember, this is just the beginning. Explore the Harvest API documentation for more endpoints and features.

Now go forth and code! Your time tracking game is about to level up. Happy harvesting!