Skip to content
This repository has been archived by the owner on Apr 5, 2022. It is now read-only.

Getting Started

jbrisbin edited this page Oct 23, 2012 · 2 revisions

Getting Started with the rest-shell

The goal of the rest-shell is to make it much easier to work with HATEOAS HTTP-based REST services by providing a command shell interface that keeps track of where you are in the HTTP resource hierarchy and allow you to specify URLs by short, relative paths, or by rel reference.

Installation

Releases can be downloaded from the GitHub rest-shell downloads page or built from source.

If you're using Mac OS X and Homebrew, you can install the rest-shell using brew install (NOTE: when the pull request is accepted...still waiting on that):

	> brew install rest-shell
	==> Downloading https://github.com/downloads/jbrisbin/rest-shell/rest-shell-1.1.2.RELEASE.tar.gz
	######################################################################## 100.0%
	/usr/local/Cellar/rest-shell/1.1.2.RELEASE: 28 files, 6.0M, built in 27 seconds

Navigation

Using the rest-shell to navigate your REST resources is very similar to traversing a directory structure in your system terminal. The rest-shell always maintains a baseUri that is considered the root to which all other path references are considered relative. If you have a REST service exposed at http://localhost:8080/api, then you'd consider that your baseUri.

But your base URI will change based on the context in which you are issuing requests. For example, if you have a REST resource exposed at /system/main, then your rest-shell interaction might look like this:

	> rest-shell

	 ___ ___  __ _____  __  _  _     _ _  __    
	| _ \ __/' _/_   _/' _/| || |   / / | \ \   
	| v / _|`._`. | | `._`.| >< |  / / /   > >  
	|_|_\___|___/ |_| |___/|_||_| |_/_/   /_/   

	Welcome to the REST shell. For assistance hit TAB or type "help".
	http://localhost:8080:> baseUri http://localhost:8080/api
	Base URI set to 'http://localhost:8080/api'
	http://localhost:8080/api:> get system/main
	> GET http://localhost:8080/api/system/main

	< 200 OK
	< ... response from server

Following a URI

One of the central tenets of HATEOAS is discoverability via links. The rest-shell understands links natively if they conform to the Spring HATEOAS pattern. You don't have to be using the Spring HATEOAS library for your server-side resources (though it's definitely encouraged that you do). If the JSON resource returned contains a property called links which is an array of objects with a rel and href property, then the rest-shell can "discover" these resources and provide you an easy way to refer to these URIs later.

For example, if I'm using the Spring Data REST project to export my JPA Entities as RESTful services, I'll receive a list of links to the repositories being exported if I request the root URL of the application. Assuming my WAR is deployed on the context path /data, I can discover those resources by using the rest-shell command discover:

	http://localhost:8080:> discover http://localhost:8080/data
	rel                href                                          
	=================================================================
	address            http://localhost:8080/data/address        
	family             http://localhost:8080/data/family         
	customerTracker    http://localhost:8080/data/customerTracker
	customer           http://localhost:8080/data/customer       
	people             http://localhost:8080/data/people         
	profile            http://localhost:8080/data/profile        

	http://localhost:8080/data:> 

NOTE: Since the rest-shell understands relative paths so well, we could have easily substituted discover data here and got the same result.

This table is built up from JSON that looks like this:

	{
	  "links" : [ {
	    "rel" : "address",
	    "href" : "http://localhost:8080/data/address"
	  }, {
	    "rel" : "family",
	    "href" : "http://localhost:8080/data/family"
	  }, {
	    "rel" : "customerTracker",
	    "href" : "http://localhost:8080/data/customerTracker"
	  }, {
	    "rel" : "customer",
	    "href" : "http://localhost:8080/data/customer"
	  }, {
	    "rel" : "people",
	    "href" : "http://localhost:8080/data/people"
	  }, {
	    "rel" : "profile",
	    "href" : "http://localhost:8080/data/profile"
	  } ],
	  "content" : [ ]
	}

Once a resource has been "discovered", I can replace references to the absolute or relative URI with a reference to the rel. This includes tab completeion support. To test this, type the following in the rest-shell:

	http://localhost:8080/data:> follow --rel p<TAB>

	people    profile   

	http://localhost:8080/data:> follow --rel people

This saves a lot of typing because I don't have to continually type out (or copy and paste) the full URI to the resource I'm interested in.

Listing resources

The follow command we used above just resets the baseUri but doesn't query the REST server to find out what links are available from the current context like the discover command does. If you want to know what resources are available at the present baseUri, though, you use the list command:

	http://localhost:8080/data/people:> list
	rel              href                                    
	=========================================================
	people.Person    http://localhost:8080/data/people/1     
	people.Person    http://localhost:8080/data/people/2     
	people.search    http://localhost:8080/data/people/search

	http://localhost:8080/data/people:> 

You can also list resources found at relative paths beneath the current baseUri without altering the current baseUri:

	http://localhost:8080/data/people:> list search
	rel                      href                                                   
	================================================================================
	people.id                http://localhost:8080/data/people/search/id            
	people.names             http://localhost:8080/data/people/search/name          
	people.count             http://localhost:8080/data/people/search/count         
	people.created           http://localhost:8080/data/people/search/created       
	people.nameStartsWith    http://localhost:8080/data/people/search/nameStartsWith

	http://localhost:8080/data/people:> 

HTTP GET

To GET a resource, use the get command. If you type help get in the rest-shell, you'll get a comprehensive list of the options available on this command. For example, to get the resource with the rel people.count, type:

	http://localhost:8080/data/people:> get --rel people.count 
	> GET http://localhost:8080/data/people/search/count

	< 200 OK
	< Content-Length: 40
	< Content-Type: application/json
	< 
	{
	  "links" : [ ],
	  "content" : [ 2 ]
	}
	http://localhost:8080/data/people:> 

If you're geting a resource that requires query parameters, you don't include them yourself in the path by adding a question mark. There is some underlying munging of text that needs to happen first (mainly proper URL encoding). Instead, you set query parameters as a JSON fragment:

	http://localhost:8080/data/people:> get --rel people.nameStartsWith --params "{name: 'John'}"
	> GET http://localhost:8080/data/people/search/nameStartsWith?name=John

	< 200 OK
	< Content-Length: 643
	< Content-Type: application/json
	< 
	{
	  "links" : [ ],
	  "content" : [ {
	    ... response
	  } ]
	}
	http://localhost:8080/data/people:> 

If you expect to get a redirect via Location header and you want to immediately follow that redirect, add the --follow true option to the get command.

If you want to pipe the output to a local file rather than dumping it into the console, then provide a file name on the --output option:

	http://localhost:8080/data/people:> get --rel people.count --output people_count.txt
	>> people_count.txt
	http://localhost:8080/data/people:> ! cat people_count.txt
	command is:cat people_count.txt
	> GET http://localhost:8080/data/people/search/count

	< 200 OK
	< Date: Mon, 22 Oct 2012 19:07:40 GMT
	< Content-Length: 40
	< Content-Type: application/json
	< Server: Jetty(8.1.5.v20120716)
	< 
	{
	  "links" : [ ],
	  "content" : [ 2 ]
	}
	http://localhost:8080/data/people:> 

NOTE: The "bang", or exclamation mark, is the command inside the Spring shell that says "run this on the underlying terminal".

HTTP POST

To send data to the server, either include a JSON fragment inline in the --data option, provide an expression that will evaluate to an object to serialize (more on this on the page describing context variable and expression language support), or specify a file or directory of files from which to read the JSON to send to the server.

Including JSON inline

To send JSON data directly inline from the rest-shell, simply include it as the string argument to the --data option. Keep in mind, however, that there are some limitations in the shell parsing, so you need to use either single quotes for strings inside your JSON, or make sure they are properly backslashed (the former is much easier, though not technically "proper" JSON). To make it easier to read the JSON going out to the server, it's also possible to omit quotes around field names. You're probably used to doing this in Javascript, but it's not technically proper JSON. No matter! The rest-shell is all about making your life easier, so the rest-shell takes a very laissez-faire attitude toward the JSON you include on the command line.

	http://localhost:8080/data/people:> post --data "{name: 'John Doe'}"
	> POST http://localhost:8080/data/people/

	< 201 CREATED
	< Location: http://localhost:8080/data/people/3
	< Content-Length: 0
	< Content-Type: text/html
	< 

	http://localhost:8080/data/people:>