Hey there, fellow developer! Ready to dive into the world of Azure DevOps API integration using Ruby? You're in for a treat! We'll be using the nifty omniauth-azure-devops package to make our lives easier. Buckle up, and let's get coding!
Before we jump in, make sure you've got:
Got those? Great! Let's move on.
First things first, let's create a new Ruby project:
mkdir azure_devops_integration cd azure_devops_integration bundle init
Now, open up that Gemfile and add these gems:
gem 'sinatra' gem 'omniauth-azure-devops' gem 'httparty'
Run bundle install
, and we're off to the races!
Time to set up our OmniAuth middleware. Create a new file called app.rb
and add this:
require 'sinatra' require 'omniauth-azure-devops' use OmniAuth::Builder do provider :azure_devops, ENV['AZURE_CLIENT_ID'], ENV['AZURE_CLIENT_SECRET'] end
Don't forget to set those environment variables with your Azure DevOps app credentials!
Let's add some routes to handle authentication:
get '/auth/azure_devops' do # This route will trigger the authentication process end get '/auth/azure_devops/callback' do auth = request.env['omniauth.auth'] session[:token] = auth['credentials']['token'] "Authentication successful!" end
Now for the fun part - let's fetch some work items:
get '/work_items' do response = HTTParty.get( 'https://dev.azure.com/{organization}/{project}/_apis/wit/workitems?api-version=6.0', headers: { 'Authorization' => "Bearer #{session[:token]}", 'Content-Type' => 'application/json' } ) response.body end
Azure DevOps API uses pagination for large datasets. Here's a quick way to handle it:
def fetch_all_work_items items = [] continuation_token = nil loop do response = fetch_work_items(continuation_token) items += response['value'] continuation_token = response['continuationToken'] break if continuation_token.nil? sleep 1 # Respect rate limits end items end
Always be prepared for things to go wrong:
def make_api_request(url) response = HTTParty.get(url, headers: { 'Authorization' => "Bearer #{session[:token]}" }) case response.code when 200 response.body when 401 logger.error "Unauthorized: Token may have expired" nil else logger.error "API request failed: #{response.code} - #{response.message}" nil end rescue StandardError => e logger.error "Error making API request: #{e.message}" nil end
Don't forget to test! Here's a simple RSpec example:
RSpec.describe "Azure DevOps Integration" do it "authenticates successfully" do get '/auth/azure_devops/callback' expect(last_response).to be_ok expect(session[:token]).not_to be_nil end end
Remember to cache API responses when possible and use API resources efficiently. Your future self (and your API quota) will thank you!
And there you have it! You've just built a Ruby integration with the Azure DevOps API. Pretty cool, right? Remember, this is just the beginning. There's so much more you can do with this API, so keep exploring and building awesome things!
Happy coding, and may your builds always be green! 🚀