Searching With the Sonatype Nexus REST API: Ruby

By

4 minute read time

When you search for artifacts using http://repository.sonatype.org, the browser queries the Nexus repository using a REST API. In this post, I'm going to show you some simple Ruby scripts which you can use to search the Maven repository without loading up the Nexus web interface. You might find these scripts more convenient and customizable, and you should copy and modify them for your own use.

The following scripts are in Ruby, and they use the REXML XML processor and the Net:HTTP library. Both of these libraries are available in the Ruby standard library. I tested these Ruby scripts using the latest JRuby release. If you want to try these scripts on your own, they will run in any standard Ruby interpreter without requiring any extra RubyGems.

The Nexus REST API

The UI of Nexus is written in ExtJS, and uses AJAX callbacks to REST services. In fact, if you load up Nexus in a tool like Firebug, an extension for Firefox that allows you to trace all network activity, you will see that almost every action in Nexus triggers a call to a REST service. We're going to focus on two services in this post: list repositories and search for artifacts, but you should know that there are hundreds of things you can do to Nexus via the various REST interfaces available. In fact, you could create a custom UI tailored to your own needs that interfaces with Nexus via this REST backend. In addition to the REST services in the core Nexus installation, you can extend Nexus and add in your own REST services via a Nexus plugin. The Nexus UI is completely decoupled from the services Nexus provides, and the services Nexus provides can be extended.

The Nexus REST Services are documented here. In this post, we'll write scripts that hit the public instance of Sonatype Nexus at http://repository.sonatype.org.

Listing Repositories

The first script simply lists all the repositories in a Nexus installation.

Here it is:

require 'net/http'
require 'rexml/document'
include REXML

url = 'http://repository.sonatype.org/service/local/repositories'
resp = Net::HTTP.get_response( URI.parse( url ) )

doc = REXML::Document.new( resp.body )

XPath.each( doc, "//repositories-item" ) do |r|
  puts "#{r.elements["name"].text}(#{r.elements["id"].text})"
  puts "\t" + r.elements["resourceURI"].text + "\n\n"
end

This script sets the pattern for the scripts to follow. We construct a URL in the script (a more general script would read this from a config file), then we make the request using Net::HTTP and we parse the results with REXML by passing it to the Document constructor. At this point, I use XPath to select all the repositories, and I print out the name, id, and URL of the repository as served by Nexus.

This post is simply a pointer to the service and a quick demonstration, so I'm not going to dive into the meaning of every element in the XML document returned by the repositories service.

Performing a "Quick Search"

require 'net/http'
require 'rexml/document'
include REXML

url = 'http://repository.sonatype.org/service/local/data_index?q='
resp = Net::HTTP.get_response( URI.parse( url + ARGV[0]) )

doc = REXML::Document.new( resp.body )

XPath.each( doc, "//data/artifact" ) do |r|
  puts "#{r.elements["groupId"].text}:#{r.elements["artifactId"].text}:#{r.elem\
ents["version"].text}"
end

This script follows the pattern of the previous script to list all repositories, with the exception that it reads an argument from the command line. This script performs a quick search by hitting the data_index service and passing in the q parameter. This script simply prints out the groupId:artifactId:version of all the artifacts located.

Searching By Class Name

require 'net/http'
require 'rexml/document'
include REXML

url = 'http://repository.sonatype.org/service/local/data_index?cn='
resp = Net::HTTP.get_response( URI.parse( url + ARGV[0]) )

doc = REXML::Document.new( resp.body )

XPath.each( doc, "//data/artifact" ) do |r|
  puts "#{r.elements["groupId"].text}:#{r.elements["artifactId"].text}:#{r.elem\
ents["version"].text}"
end

This script is almost exactly the same as the previous script that performed a quick search. The difference in this script is that instead of passing the q parameter, this script passes the cn parameter. Passing the cn parameter causes Nexus to search for artifacts that contain classes that match the given value. The results will look the same as the quick search query script. To see the XML yourself, search for all artifacts which contain a class named HibernateDaoSupport: http://repository.sonatype.org/service/local/data_index?cn=HibernateDaoSupport.

Performing a GAV Search

require 'net/http'
require 'rexml/document'
include REXML

url = "http://repository.sonatype.org/service/local/data_index?g=#{ARGV[0]}&a=#\
{ARGV[1]}&v=#{ARGV[2]}"
resp = Net::HTTP.get_response( URI.parse( url ) )

doc = REXML::Document.new( resp.body )

XPath.each( doc, "//data/artifact" ) do |r|
  puts "#{r.elements["groupId"].text}:#{r.elements["artifactId"].text}:#{r.elem\
ents["version"].text}"
end

This final script takes three command line arguments: groupId, artifactId, version, and it performs a GAV (groupId, artifactId, version) coordinate search over the repository.

Picture of Tim OBrien

Written by Tim OBrien

Tim is a Software Architect with experience in all aspects of software development from project inception to developing scaleable production architectures for large-scale systems during critical, high-risk events such as Black Friday. He has helped many organizations ranging from small startups to ...

Tags