Update the documentation.
This commit is contained in:
@@ -43,7 +43,10 @@
|
|||||||
</toc>
|
</toc>
|
||||||
|
|
||||||
<xi:include href="intro.xml"/>
|
<xi:include href="intro.xml"/>
|
||||||
<xi:include href="representations.xml"/>
|
|
||||||
<xi:include href="install.xml"/>
|
<xi:include href="install.xml"/>
|
||||||
|
<xi:include href="representations.xml"/>
|
||||||
|
<xi:include href="paging.xml"/>
|
||||||
|
<xi:include href="validation.xml"/>
|
||||||
|
<xi:include href="rest-shell.xml"/>
|
||||||
|
|
||||||
</book>
|
</book>
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
<title>Installing Spring Data REST</title>
|
<title>Installing Spring Data REST</title>
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
<title>Adding Spring Data REST to an existing Spring MVC application</title>
|
<title>Introduction</title>
|
||||||
|
|
||||||
<para>Spring Data REST is itself a Spring MVC application and is designed in such a way that it should integrate
|
<para>Spring Data REST is itself a Spring MVC application and is designed in such a way that it should integrate
|
||||||
with your existing Spring MVC applications with very little effort. An existing (or future) layer of services can
|
with your existing Spring MVC applications with very little effort. An existing (or future) layer of services can
|
||||||
@@ -20,7 +20,171 @@
|
|||||||
class (or subclass it and perform any required manual configuration), and map some URLs to be managed by Spring
|
class (or subclass it and perform any required manual configuration), and map some URLs to be managed by Spring
|
||||||
Data REST.
|
Data REST.
|
||||||
</para>
|
</para>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<title>Adding Spring Data REST to a Gradle project</title>
|
||||||
|
|
||||||
|
<para>To add Spring Data REST to a Gradle-based project, add the
|
||||||
|
<code>spring-data-rest-webmvc</code>
|
||||||
|
artifact to your compile-time dependencies:
|
||||||
|
|
||||||
|
<programlisting><![CDATA[dependencies {
|
||||||
|
... other project dependencies
|
||||||
|
compile "org.springframework.data:spring-data-rest-webmvc:1.1.0.M1"
|
||||||
|
}]]></programlisting>
|
||||||
|
</para>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<title>Adding Spring Data REST to a Maven project</title>
|
||||||
|
|
||||||
|
<para>To add Spring Data REST to a Maven-based project, add the
|
||||||
|
<code>spring-data-rest-webmvc</code>
|
||||||
|
artifact to your compile-time dependencies:
|
||||||
|
|
||||||
|
<programlisting><![CDATA[<dependency>
|
||||||
|
<groupId>org.springframework.data</groupId>
|
||||||
|
<artifactId>spring-data-rest-webmvc</artifactId>
|
||||||
|
<version>1.1.0.M1</version>
|
||||||
|
</dependency>]]></programlisting>
|
||||||
|
</para>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<title>Configuring Spring Data REST</title>
|
||||||
|
|
||||||
|
<para>To install Spring Data REST alongside your existing Spring MVC application, you need to include the
|
||||||
|
appropriate MVC configuration. Spring Data REST configuration is defined in a class called
|
||||||
|
<classname>RepositoryRestMvcConfiguration</classname>. You can either import this class into your existing
|
||||||
|
configuration using an
|
||||||
|
<code>@Import</code>
|
||||||
|
annotation or you can subclass it and override any of the
|
||||||
|
<code>configureXXX</code>
|
||||||
|
methods to add your own configuration to that of Spring Data REST.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>In the following example, we'll subclass the standard
|
||||||
|
<classname>RepositoryRestMvcConfiguration</classname>
|
||||||
|
and add some
|
||||||
|
<classname>ResourceMapping</classname>
|
||||||
|
configurations for the
|
||||||
|
<classname>Person</classname>
|
||||||
|
domain object to alter how the JSON will look and how the links to related entities will be handled.
|
||||||
|
|
||||||
|
<programlisting language="java"><![CDATA[
|
||||||
|
@Configuration
|
||||||
|
public class MyWebConfiguration extends RepositoryRestMvcConfiguration {
|
||||||
|
|
||||||
|
@Override protected void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
|
||||||
|
config.addResourceMappingForDomainType(Person.class)
|
||||||
|
.addResourceMappingFor("lastName")
|
||||||
|
.setPath("surname"); // Change 'lastName' to 'surname' in the JSON
|
||||||
|
config.addResourceMappingForDomainType(Person.class)
|
||||||
|
.addResourceMappingFor("siblings")
|
||||||
|
.setRel("siblings")
|
||||||
|
.setPath("siblings"); // Pointless in this example,
|
||||||
|
// but shows how to change 'rel' and 'path' values.
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
]]></programlisting>
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>There are numerous methods on the
|
||||||
|
<classname>RepositoryRestConfiguration</classname>
|
||||||
|
object to allow you to configure various aspects of Spring Data REST. Please read the javadoc for that class to
|
||||||
|
get detailed descriptions of the various settings you can control.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<title>Adding custom converters</title>
|
||||||
|
|
||||||
|
<para>It may be necessary to add a custom converter to Spring Data REST. You might need to turn a query parameter
|
||||||
|
into a complex object, for instance. In that case, you'll want to override the
|
||||||
|
<code>configureConversionService</code>
|
||||||
|
method and add your own converters. To convert a query parameter to a complex object, for instance, you would
|
||||||
|
want to register a converter for
|
||||||
|
<classname>String[]</classname>
|
||||||
|
to
|
||||||
|
<classname>MyPojo</classname>.
|
||||||
|
|
||||||
|
<programlisting language="java"><![CDATA[
|
||||||
|
@Bean public MyPojoConverter myPojoConverter() {
|
||||||
|
return new MyPojoConverter();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override protected void configureConversionService(ConfigurableConversionService conversionService) {
|
||||||
|
conversionService.addConverter(String[].class, myPojoConverter());
|
||||||
|
}]]></programlisting>
|
||||||
|
</para>
|
||||||
|
</section>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<title>Adding Spring Data REST to Spring MVC</title>
|
||||||
|
|
||||||
|
<para>Since Spring Data REST is simply a Spring MVC application, you only need to include the REST configuration
|
||||||
|
into the configuration for the
|
||||||
|
<classname>DispatcherServlet</classname>. If using a Servlet 3.0
|
||||||
|
<classname>WebApplicationInitializer</classname>
|
||||||
|
(the preferred configuration for Spring Data REST applications), you would add your subclassed configuration
|
||||||
|
from above into the configuration for the
|
||||||
|
<classname>DispatcherServlet</classname>. The following configuration class is from the example project and
|
||||||
|
includes datasource configuration for three different datastores and domain models, which will all be exported
|
||||||
|
by Spring Data REST.
|
||||||
|
|
||||||
|
<programlisting language="java"><![CDATA[
|
||||||
|
public class RestExporterWebInitializer implements WebApplicationInitializer {
|
||||||
|
|
||||||
|
@Override public void onStartup(ServletContext servletContext) throws ServletException {
|
||||||
|
AnnotationConfigWebApplicationContext rootCtx = new AnnotationConfigWebApplicationContext();
|
||||||
|
rootCtx.register(
|
||||||
|
JpaRepositoryConfig.class, // Include JPA entities, Repositories
|
||||||
|
MongoDbRepositoryConfig.class, // Include MongoDB document entities, Repositories
|
||||||
|
GemfireRepositoryConfig.class // Inlucde Gemfire entities, Repositories
|
||||||
|
);
|
||||||
|
servletContext.addListener(new ContextLoaderListener(rootCtx));
|
||||||
|
|
||||||
|
AnnotationConfigWebApplicationContext webCtx = new AnnotationConfigWebApplicationContext();
|
||||||
|
webCtx.register(MyWebConfiguration.class);
|
||||||
|
|
||||||
|
DispatcherServlet dispatcherServlet = new DispatcherServlet(webCtx);
|
||||||
|
ServletRegistration.Dynamic reg = servletContext.addServlet("rest-exporter", dispatcherServlet);
|
||||||
|
reg.setLoadOnStartup(1);
|
||||||
|
reg.addMapping("/*");
|
||||||
|
}
|
||||||
|
|
||||||
|
}]]></programlisting>
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>The equivalent of the above in a standard web.xml will also work identically to this configuration if you
|
||||||
|
are still in a servlet 2.5 environment.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>When you deploy this application to your servlet container, you should be able to see what
|
||||||
|
repositories are exported by accessing the root of the application. You can use curl or, more easily, the
|
||||||
|
<code>rest-shell</code>:
|
||||||
|
|
||||||
|
<programlisting><![CDATA[$ rest-shell
|
||||||
|
|
||||||
|
___ ___ __ _____ __ _ _ _ _ __
|
||||||
|
| _ \ __/' _/_ _/' _/| || | / / | \ \
|
||||||
|
| v / _|`._`. | | `._`.| >< | / / / > >
|
||||||
|
|_|_\___|___/ |_| |___/|_||_| |_/_/ /_/
|
||||||
|
1.2.1.RELEASE
|
||||||
|
|
||||||
|
Welcome to the REST shell. For assistance hit TAB or type "help".
|
||||||
|
http://localhost:8080:> list
|
||||||
|
rel href
|
||||||
|
==========================================
|
||||||
|
people http://localhost:8080/people
|
||||||
|
profile http://localhost:8080/profile
|
||||||
|
customer http://localhost:8080/customer
|
||||||
|
order http://localhost:8080/order
|
||||||
|
product http://localhost:8080/product
|
||||||
|
]]></programlisting>
|
||||||
|
</para>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
</chapter>
|
</chapter>
|
||||||
@@ -168,617 +168,4 @@
|
|||||||
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section xml:id="rest-shell">
|
|
||||||
<title>Using the
|
|
||||||
<command>rest-shell</command>
|
|
||||||
</title>
|
|
||||||
|
|
||||||
<para>The
|
|
||||||
<link xlink:href="https://github.com/SpringSource/rest-shell">
|
|
||||||
<command>rest-shell</command>
|
|
||||||
</link>
|
|
||||||
is a command-line shell that aims to make writing REST-based applications easier. It is based on spring-shell and
|
|
||||||
integrated with Spring HATEOAS in such a way that REST resources that output JSON compliant with Spring HATEOAS
|
|
||||||
can be discovered by the shell and interactions with the REST resources become much easier than by manipulating
|
|
||||||
the URLs in bash using a tool like
|
|
||||||
<command>curl</command>.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>The rest-shell provides a number of useful commands for discovering and interacting with REST resources. For
|
|
||||||
example discover will discover what resources are available and print out an easily-readable table of rels and
|
|
||||||
URIs that relate to those resources. Once these resources have been discovered, the rel of those URIs can be used
|
|
||||||
in place of the URI itself in most operations, thus cutting down on the amount of typing needed to issue HTTP
|
|
||||||
requests to your REST resources.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<section>
|
|
||||||
<title>Installing the
|
|
||||||
<command>rest-shell</command>
|
|
||||||
</title>
|
|
||||||
|
|
||||||
<para>If you're using Mac OS X and Homebrew, then installation is super easy:</para>
|
|
||||||
|
|
||||||
<programlisting><![CDATA[brew install rest-shell]]></programlisting>
|
|
||||||
|
|
||||||
<para>Other platforms are simple as well: just download the archive from the GitHub page and unzip it to a
|
|
||||||
location on your local hard drive.
|
|
||||||
</para>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section>
|
|
||||||
<title>Discovering resources</title>
|
|
||||||
|
|
||||||
<para>The rest-shell is aimed at making it easier to interact with REST resources by managing the session baseUri
|
|
||||||
much like a directory in a filesystem. Whenever resources are discovered, you can then follow to a new baseUri,
|
|
||||||
which means you can then use relative URIs. Here's an example of discovering resources, then following a link by
|
|
||||||
referencing its rel value, and then using a relative URI to access resources under that new baseUri:
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<programlisting><![CDATA[http://localhost:8080:> discover
|
|
||||||
rel href
|
|
||||||
========================================================
|
|
||||||
address http://localhost:8080/address
|
|
||||||
family http://localhost:8080/family
|
|
||||||
people http://localhost:8080/person
|
|
||||||
profile http://localhost:8080/profile
|
|
||||||
|
|
||||||
http://localhost:8080:> follow people
|
|
||||||
http://localhost:8080/person:> list
|
|
||||||
rel href
|
|
||||||
===================================================
|
|
||||||
people.Person http://localhost:8080/person/1
|
|
||||||
people.Person http://localhost:8080/person/2
|
|
||||||
people.search http://localhost:8080/person/search
|
|
||||||
|
|
||||||
http://localhost:8080/person:> get 1
|
|
||||||
> GET http://localhost:8080/person/1
|
|
||||||
|
|
||||||
< 200 OK
|
|
||||||
< ETag: "2"
|
|
||||||
< Content-Type: application/json
|
|
||||||
<
|
|
||||||
{
|
|
||||||
"links" : [ {
|
|
||||||
"rel" : "self",
|
|
||||||
"href" : "http://localhost:8080/person/1"
|
|
||||||
}, {
|
|
||||||
"rel" : "peeps.Person.profiles",
|
|
||||||
"href" : "http://localhost:8080/person/1/profiles"
|
|
||||||
}, {
|
|
||||||
"rel" : "peeps.Person.addresses",
|
|
||||||
"href" : "http://localhost:8080/person/1/addresses"
|
|
||||||
} ],
|
|
||||||
"name" : "John Doe"
|
|
||||||
}]]></programlisting>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
<emphasis>NOTE: If you want tab completion of discovered rels, just use the --rel flag.</emphasis>
|
|
||||||
</para>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section>
|
|
||||||
<title>Creating new resources</title>
|
|
||||||
|
|
||||||
<para>The rest-shell can do basic parsing of JSON data within the shell (though there are some limitations due to
|
|
||||||
the nature of the command line parsing being sensitive to whitespace). This makes it easy to create new
|
|
||||||
resources
|
|
||||||
by including JSON data directly in the shell:
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<programlisting><![CDATA[http://localhost:8080/person:> post --data "{name: 'John Doe'}"
|
|
||||||
> POST http://localhost:8080/person/
|
|
||||||
|
|
||||||
< 201 CREATED
|
|
||||||
< Location: http://localhost:8080/person/8
|
|
||||||
< Content-Length: 0
|
|
||||||
<
|
|
||||||
|
|
||||||
http://localhost:8080/person:> get 8
|
|
||||||
> GET http://localhost:8080/person/8
|
|
||||||
|
|
||||||
< 200 OK
|
|
||||||
< ETag: "0"
|
|
||||||
< Content-Type: application/json
|
|
||||||
<
|
|
||||||
{
|
|
||||||
"links" : [ {
|
|
||||||
"rel" : "self",
|
|
||||||
"href" : "http://localhost:8080/person/8"
|
|
||||||
}, {
|
|
||||||
"rel" : "people.Person.addresses",
|
|
||||||
"href" : "http://localhost:8080/person/8/addresses"
|
|
||||||
}, {
|
|
||||||
"rel" : "people.Person.profiles",
|
|
||||||
"href" : "http://localhost:8080/person/8/profiles"
|
|
||||||
} ],
|
|
||||||
"name" : "John Doe"
|
|
||||||
}]]></programlisting>
|
|
||||||
|
|
||||||
<para>If your needs of representing JSON get more complicated than what the spring-shell interface can handle, you
|
|
||||||
can create a directory somewhere with .json files in it, one file per entitiy, and use the --from option to the
|
|
||||||
post command. This will walk the directory and make a POST request for each .json file found.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<programlisting><![CDATA[http://localhost:8080/person:> post --from work/people_to_load
|
|
||||||
128 items uploaded to the server using POST.
|
|
||||||
http://localhost:8080/person:>]]></programlisting>
|
|
||||||
|
|
||||||
<para>You can also reference a specific file rather than an entire directory.</para>
|
|
||||||
|
|
||||||
<programlisting><![CDATA[http://localhost:8080/person:> post --from work/people_to_load/someone.json
|
|
||||||
1 items uploaded to the server using POST.
|
|
||||||
http://localhost:8080/person:>]]></programlisting>
|
|
||||||
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section>
|
|
||||||
<title>Passing query parameters</title>
|
|
||||||
|
|
||||||
<para>If you're calling URLs that require query parameters, you'll need to pass those as a JSON-like fragment in
|
|
||||||
the --params parameter to the get and list commands. Here's an example of calling a URL that expects parameter
|
|
||||||
input:
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<programlisting><![CDATA[http://localhost:8080/person:> get search/byName --params "{name: 'John Doe'}"]]>
|
|
||||||
</programlisting>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section>
|
|
||||||
<title>Outputing results to a file</title>
|
|
||||||
|
|
||||||
<para>It's not always desirable to output the results of an HTTP request to the screen. It's handy for debugging
|
|
||||||
but
|
|
||||||
sometimes you want to save the results of a request because they're not easily reproducible or any number of
|
|
||||||
other
|
|
||||||
equally valid reasons. All the HTTP commands take an --output parameter that writes the results of an HTTP
|
|
||||||
operation to the given file. For example, to output the above search to a file:
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<programlisting><![CDATA[http://localhost:8080/person:> get search/byName --params "{name: 'John Doe'}" --output by_name.txt >> by_name.txt
|
|
||||||
http://localhost:8080/person:>]]></programlisting>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section>
|
|
||||||
<title>Sending complex JSON</title>
|
|
||||||
|
|
||||||
<para>Because the rest-shell uses the spring-shell underneath, there are limitations on the format of the JSON
|
|
||||||
data
|
|
||||||
you can enter directly into the command line. If your JSON is too complex for the simplistic limitations of the
|
|
||||||
shell --data parameter, you can simply load the JSON from a file or from all the files in a directory.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>When doing a post or put, you can optionally pass the --from parameter. The value of this parameter should
|
|
||||||
either be a file or a directory. If the value is a directory, the shell will read each file that ends with .json
|
|
||||||
and make a POST or PUT with the contents of that file. If the parameter is a file, then the rest-shell will
|
|
||||||
simpy
|
|
||||||
load that file and POST/PUT that data in that individual file.
|
|
||||||
</para>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section>
|
|
||||||
<title>Shelling out to bash</title>
|
|
||||||
|
|
||||||
<para>One of the nice things about spring-shell is that you can directly shell out commands to the underlying
|
|
||||||
terminal shell. This is useful for doing things like load a JSON file in an editor. For instance, assume I have
|
|
||||||
the Sublime Text 2 command subl in my path. I can then load a JSON file for editing from the rest-shell like
|
|
||||||
this:
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<programlisting><![CDATA[http://localhost:8080/person:> ! subl test.json
|
|
||||||
http://localhost:8080/person:>]]></programlisting>
|
|
||||||
|
|
||||||
<para>I then edit the file as I wish. When I'm ready to POST that data to the server, I can do so using the --from
|
|
||||||
parameter:
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<programlisting><![CDATA[http://localhost:8080/person:> post --from test.json
|
|
||||||
1 items uploaded to the server using POST.
|
|
||||||
http://localhost:8080/person:>]]></programlisting>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
|
|
||||||
<section>
|
|
||||||
<title>Setting context variables</title>
|
|
||||||
|
|
||||||
<para>Starting with rest-shell version 1.1, you can also work with context variables during your shell session.
|
|
||||||
This
|
|
||||||
is useful for saving settings you might reference often. The rest-shell now integrates Spring Expression
|
|
||||||
Language
|
|
||||||
support, so these context variables are usable in expressions within the shell.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
|
|
||||||
<programlisting><![CDATA[http://localhost:8080/person:> var set --name specialUri --value http://longdomainname.com/api
|
|
||||||
http://localhost:8080/person:> var get --name specialUri
|
|
||||||
http://longdomainname.com/api
|
|
||||||
http://localhost:8080/person:> var list
|
|
||||||
{
|
|
||||||
"responseHeaders" : {
|
|
||||||
... HTTP headers from last request
|
|
||||||
},
|
|
||||||
"responseBody" : {
|
|
||||||
... Body from the last request
|
|
||||||
},
|
|
||||||
"specialUri" : "http://longdomainname.com/api",
|
|
||||||
"requestUrl" : ... URL from the last request,
|
|
||||||
"env" : {
|
|
||||||
... System properties and environment variables
|
|
||||||
}
|
|
||||||
}]]></programlisting>
|
|
||||||
|
|
||||||
<para>The variables are accessible from SpEL expressions which are valid in a number of different contexts, most
|
|
||||||
importantly in the path argument to the HTTP and discover commands, and in the data argument to the put and post
|
|
||||||
commands.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>Since the rest-shell is aware of environment variables and system properties, you can incorporate external
|
|
||||||
parameters into your interaction with the shell. For example, to externally define a baseUri, you could set a
|
|
||||||
system property before invoking the shell. The shell will incorporate anything defined in the JAVA_OPTS
|
|
||||||
environment variable, so you could parameterize your interaction with a REST service.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<programlisting><![CDATA[JAVA_OPTS="-DbaseUri=http://mylongdomain.com/api" rest-shell
|
|
||||||
|
|
||||||
http://localhost:8080:> discover #{env.baseUri}
|
|
||||||
rel href
|
|
||||||
=================================================================
|
|
||||||
... resources for this URL
|
|
||||||
http://mylongdomain.com/api:>]]></programlisting>
|
|
||||||
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section>
|
|
||||||
<title>Per-user shell initialization</title>
|
|
||||||
|
|
||||||
<para>The rest-shell supports a "dotrc" type of initialization by reading in all files found in the
|
|
||||||
$HOME/.rest-shell/ directory and assuming they have shell commands in them. The rest-shell will execute these
|
|
||||||
commands on startup. This makes it easy to set variables for commonly-used URIs or possibly set a baseUri.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<programlisting><![CDATA[echo "var set --name svcuri --value http://api.myservice.com/v1" > ~/.rest-shell/00-vars
|
|
||||||
echo "discover #{svcuri}" > ~/.rest-shell/01-baseUri
|
|
||||||
|
|
||||||
> rest-shell
|
|
||||||
|
|
||||||
INFO: No resources found...
|
|
||||||
INFO: Base URI set to 'http://api.myservice.com/v1'
|
|
||||||
|
|
||||||
___ ___ __ _____ __ _ _ _ _ __
|
|
||||||
| _ \ __/' _/_ _/' _/| || | / / | \ \
|
|
||||||
| v / _|`._`. | | `._`.| >< | / / / > >
|
|
||||||
|_|_\___|___/ |_| |___/|_||_| |_/_/ /_/
|
|
||||||
1.2.1.RELEASE
|
|
||||||
|
|
||||||
Welcome to the REST shell. For assistance hit TAB or type "help".
|
|
||||||
http://api.myservice.com/v1:>]]></programlisting>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section>
|
|
||||||
<title>SSL Certificate Validation</title>
|
|
||||||
|
|
||||||
<para>If you generate a self-signed certificate for your server, by default the rest-shell will complain and
|
|
||||||
refuse
|
|
||||||
to connect. This is the default behavior of RestTemplate. To turn off certificate and hostname checking, use the
|
|
||||||
ssl validate --enabled false command.
|
|
||||||
</para>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section>
|
|
||||||
<title>HTTP Basic authentication</title>
|
|
||||||
|
|
||||||
<para>There is also a convenience command for setting an HTTP Basic authentication header. Use auth basic
|
|
||||||
--username
|
|
||||||
user --pasword passwd to set a username and password to base64 encode and place into the Authorization header
|
|
||||||
that
|
|
||||||
will be part of the current session's headers.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>You can clear the authentication by using the auth clear command or by removing the Authorization header
|
|
||||||
using
|
|
||||||
the headers clear command.
|
|
||||||
</para>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section>
|
|
||||||
<title>Commands</title>
|
|
||||||
|
|
||||||
<para>The rest-shell provides the following commands:</para>
|
|
||||||
|
|
||||||
<table>
|
|
||||||
<caption>rest-shell commands</caption>
|
|
||||||
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>Command</th>
|
|
||||||
<th>Description</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<cmdsynopsis>
|
|
||||||
<command>baseUri</command>
|
|
||||||
<arg choice="req">
|
|
||||||
<replaceable>uri</replaceable>
|
|
||||||
</arg>
|
|
||||||
</cmdsynopsis>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<para>Set the base URI used for this point forward in the session. Relative URIs will be calculated relative
|
|
||||||
to this setting.
|
|
||||||
</para>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<cmdsynopsis>
|
|
||||||
<command>discover</command>
|
|
||||||
<group>
|
|
||||||
<arg>--rel
|
|
||||||
<replaceable>rel</replaceable>
|
|
||||||
</arg>
|
|
||||||
<arg>
|
|
||||||
<replaceable>path</replaceable>
|
|
||||||
</arg>
|
|
||||||
</group>
|
|
||||||
</cmdsynopsis>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<para>Find out what resources are available at the given URI. If no URI is given, use the baseUri.
|
|
||||||
</para>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<cmdsynopsis>
|
|
||||||
<command>follow</command>
|
|
||||||
<group>
|
|
||||||
<arg>--rel
|
|
||||||
<replaceable>rel</replaceable>
|
|
||||||
</arg>
|
|
||||||
<arg>
|
|
||||||
<replaceable>path</replaceable>
|
|
||||||
</arg>
|
|
||||||
</group>
|
|
||||||
</cmdsynopsis>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<para>Set the baseUri to the URI assigned to this given rel or path but do not discover resources.
|
|
||||||
</para>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<cmdsynopsis>
|
|
||||||
<command>list</command>
|
|
||||||
<group>
|
|
||||||
<arg>--rel
|
|
||||||
<replaceable>rel</replaceable>
|
|
||||||
</arg>
|
|
||||||
<arg>
|
|
||||||
<replaceable>path</replaceable>
|
|
||||||
</arg>
|
|
||||||
</group>
|
|
||||||
<arg>--params
|
|
||||||
<replaceable>JSON</replaceable>
|
|
||||||
</arg>
|
|
||||||
</cmdsynopsis>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<para>Find out what resources are available at the given URI.
|
|
||||||
</para>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<cmdsynopsis>
|
|
||||||
<command>headers set</command>
|
|
||||||
<arg choice="req">--name
|
|
||||||
<replaceable>name</replaceable>
|
|
||||||
</arg>
|
|
||||||
<arg choice="req">--value
|
|
||||||
<replaceable>value</replaceable>
|
|
||||||
</arg>
|
|
||||||
</cmdsynopsis>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<para>Set an HTTP header for use from this point forward in the session.</para>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<cmdsynopsis>
|
|
||||||
<command>headers clear</command>
|
|
||||||
</cmdsynopsis>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<para>Clear all HTTP headers set during this session.</para>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<cmdsynopsis>
|
|
||||||
<command>headers list</command>
|
|
||||||
</cmdsynopsis>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<para>Print out the currently-set HTTP headers for this session.</para>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<cmdsynopsis>
|
|
||||||
<command>history list</command>
|
|
||||||
</cmdsynopsis>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<para>List the URIs previously set as baseUris during this session.</para>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<cmdsynopsis>
|
|
||||||
<command>history go</command>
|
|
||||||
<arg>
|
|
||||||
<replaceable>num</replaceable>
|
|
||||||
</arg>
|
|
||||||
</cmdsynopsis>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<para>Jump to a URI by pulling one from the history.</para>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<cmdsynopsis>
|
|
||||||
<command>var clear</command>
|
|
||||||
</cmdsynopsis>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<para>Clear this shell's variable context.</para>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<cmdsynopsis>
|
|
||||||
<command>var get</command>
|
|
||||||
<arg>--name
|
|
||||||
<replaceable>name</replaceable>
|
|
||||||
</arg>
|
|
||||||
<arg>--value
|
|
||||||
<replaceable>expression</replaceable>
|
|
||||||
</arg>
|
|
||||||
</cmdsynopsis>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<para>Get a variable from this shell's context by name or evaluate a shell expression.</para>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<cmdsynopsis>
|
|
||||||
<command>var list</command>
|
|
||||||
</cmdsynopsis>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<para>List variables currently set in this shell's context.</para>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<cmdsynopsis>
|
|
||||||
<command>var set</command>
|
|
||||||
</cmdsynopsis>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<para>Set a variable in this shell's context.</para>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<cmdsynopsis>
|
|
||||||
<command>up</command>
|
|
||||||
</cmdsynopsis>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<para>Traverse one level up in the URL hierarchy.</para>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<cmdsynopsis>
|
|
||||||
<command>get</command>
|
|
||||||
<group>
|
|
||||||
<arg>--rel
|
|
||||||
<replaceable>rel</replaceable>
|
|
||||||
</arg>
|
|
||||||
<arg>
|
|
||||||
<replaceable>path</replaceable>
|
|
||||||
</arg>
|
|
||||||
</group>
|
|
||||||
<arg>--follow true | false</arg>
|
|
||||||
<arg>--params
|
|
||||||
<replaceable>JSON</replaceable>
|
|
||||||
</arg>
|
|
||||||
<arg>--output
|
|
||||||
<replaceable>filename</replaceable>
|
|
||||||
</arg>
|
|
||||||
</cmdsynopsis>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<para>HTTP GET from the given path. If
|
|
||||||
<code>--follow true</code>
|
|
||||||
is set, then follow any redirects automatically. If
|
|
||||||
<code>--output filename</code>
|
|
||||||
is set, output the the response into the given file.
|
|
||||||
</para>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<cmdsynopsis>
|
|
||||||
<command>post</command>
|
|
||||||
</cmdsynopsis>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<para>HTTP POST to the given path, passing JSON given in the --data parameter.</para>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<cmdsynopsis>
|
|
||||||
<command>put</command>
|
|
||||||
</cmdsynopsis>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<para>HTTP PUT to the given path, passing JSON given in the --data parameter.</para>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<cmdsynopsis>
|
|
||||||
<command>delete</command>
|
|
||||||
</cmdsynopsis>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<para>HTTP DELETE to the given path.</para>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<cmdsynopsis>
|
|
||||||
<command>auth basic</command>
|
|
||||||
</cmdsynopsis>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<para>Set an HTTP Basic authentication token for use in this session.</para>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<cmdsynopsis>
|
|
||||||
<command>auth clear</command>
|
|
||||||
</cmdsynopsis>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<para>Clear the Authorization header currently in use.</para>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<cmdsynopsis>
|
|
||||||
<command>ssl validate</command>
|
|
||||||
</cmdsynopsis>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<para>Disable certificate checking to work with self-signed certificates.</para>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
</section>
|
|
||||||
|
|
||||||
</section>
|
|
||||||
|
|
||||||
</chapter>
|
</chapter>
|
||||||
114
src/reference/docbook/paging.xml
Normal file
114
src/reference/docbook/paging.xml
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<chapter xml:id="paging-chapter"
|
||||||
|
xmlns="http://docbook.org/ns/docbook"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://docbook.org/ns/docbook http://www.oasis-open.org/docbook/xml/5.0/xsd/docbook.xsd
|
||||||
|
http://www.w3.org/1999/xlink http://www.oasis-open.org/docbook/xml/5.0/xsd/xlink.xsd">
|
||||||
|
|
||||||
|
<title>Paging and Sorting</title>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<title>Paging</title>
|
||||||
|
|
||||||
|
<para>Rather than return everything from a large result set, Spring Data REST recognizes some URL parameters that
|
||||||
|
will
|
||||||
|
influence the page size and starting page number. To add paging support to your Repositories, you need to extend
|
||||||
|
the
|
||||||
|
<classname>PagingAndSortingRepository<T,ID></classname>
|
||||||
|
interface rather than the basic
|
||||||
|
<classname>CrudRepository<T,ID></classname>
|
||||||
|
interface. This adds methods that accept a
|
||||||
|
<classname>Pageable</classname>
|
||||||
|
to control the number and page of results returned.
|
||||||
|
|
||||||
|
<programlisting language="java"><![CDATA[public Page findAll(Pageable pageable);]]></programlisting>
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>If you extend
|
||||||
|
<classname>PagingAndSortingRepository<T,ID></classname>
|
||||||
|
and access the list of all entities, you'll get links to the first 20 entities. To set the page size to any other
|
||||||
|
number, add a limit parameter:
|
||||||
|
|
||||||
|
<programlisting><![CDATA[http://localhost:8080/people/?limit=50]]></programlisting>
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>To get paging in your query methods, you must change the signature of your query methods to accept a
|
||||||
|
<classname>Pageable</classname>
|
||||||
|
as a parameter and return a
|
||||||
|
<classname>Page<T></classname>
|
||||||
|
rather than a
|
||||||
|
<classname>List<T></classname>. Otherwise, you won't get any paging information in the JSON and
|
||||||
|
specifying the query parameters that control paging will have no effect.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>By default, the URL query parameters recognized are
|
||||||
|
<code>page</code>, to specify page number
|
||||||
|
<code>limit</code>, to specify how many results to return on a page, and
|
||||||
|
<code>sort</code>
|
||||||
|
to specify the query method parameter on which to sort. To change the names of the query parameters, simply call
|
||||||
|
the appropriate method on
|
||||||
|
<classname>RepositoryRestConfiguration</classname>
|
||||||
|
and give it the text you would like to use for the query parameter. The following, for example, would set the
|
||||||
|
paging parameter to
|
||||||
|
<code>p</code>, the limit parameter to
|
||||||
|
<code>l</code>, and the sort parameter to
|
||||||
|
<code>q</code>:
|
||||||
|
|
||||||
|
<programlisting language="java"><![CDATA[
|
||||||
|
@Override protected void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
|
||||||
|
config.setPageParamName("p")
|
||||||
|
.setLimitParamName("l")
|
||||||
|
.setSortParamName("q");
|
||||||
|
}]]></programlisting>
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>The URL to use these parameters would then be changed to:
|
||||||
|
|
||||||
|
<programlisting><![CDATA[http://localhost:8080/people/?p=2&l=50]]></programlisting>
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<title>Previous and Next Links</title>
|
||||||
|
|
||||||
|
<para>Each paged response will return links to the previous and next pages of results based on the current page.
|
||||||
|
If
|
||||||
|
you are currently at the first page of results, however, no "previous" link will be rendered. The same is true
|
||||||
|
for
|
||||||
|
the last page of results: no "next" link will be rendered if you are on the last page of results. The "rel"
|
||||||
|
value
|
||||||
|
of the link will end with ".next" for next links and ".prev" for previous links.
|
||||||
|
|
||||||
|
<programlisting><![CDATA[{
|
||||||
|
"rel" : "people.next",
|
||||||
|
"href" : "http://localhost:8080/people?page=2&limit=20"
|
||||||
|
}]]></programlisting>
|
||||||
|
</para>
|
||||||
|
</section>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<title>Sorting</title>
|
||||||
|
|
||||||
|
<para>Spring Data REST also recognizes sorting parameters that will use the Repository sorting support.</para>
|
||||||
|
|
||||||
|
<para>To have your results sorted on a particular property, add a sort URL parameter with the name of the property
|
||||||
|
you want to sort the results on. You can control the direction of the sort by specifying a URL parameter composed
|
||||||
|
of the property name plus
|
||||||
|
<code>.dir</code>
|
||||||
|
and setting that value to either
|
||||||
|
<code>asc</code>
|
||||||
|
or<code>desc</code>. The following would use the
|
||||||
|
<code>findByNameStartsWith</code>
|
||||||
|
query method defined on the
|
||||||
|
<classname>PersonRepository</classname>
|
||||||
|
for all
|
||||||
|
<classname>Person</classname>
|
||||||
|
entities with names starting with the letter "K" and add sort data that orders the results on the name property in
|
||||||
|
descending order:
|
||||||
|
|
||||||
|
<programlisting>
|
||||||
|
<![CDATA[curl -v http://localhost:8080/people/search/nameStartsWith?name=K&sort=name&name.dir=desc]]></programlisting>
|
||||||
|
</para>
|
||||||
|
</section>
|
||||||
|
</chapter>
|
||||||
@@ -1,17 +1,110 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<chapter xml:id="representations-chapter"
|
<chapter xml:id="representations-chapter"
|
||||||
xmlns="http://docbook.org/ns/docbook"
|
xmlns="http://docbook.org/ns/docbook"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xsi:schemaLocation="http://docbook.org/ns/docbook http://www.oasis-open.org/docbook/xml/5.0/xsd/docbook.xsd">
|
xsi:schemaLocation="http://docbook.org/ns/docbook http://www.oasis-open.org/docbook/xml/5.0/xsd/docbook.xsd
|
||||||
|
http://www.w3.org/1999/xlink http://www.oasis-open.org/docbook/xml/5.0/xsd/xlink.xsd">
|
||||||
|
|
||||||
<title>Domain Object Representations</title>
|
<title>Domain Object Representations</title>
|
||||||
|
|
||||||
<section xml:id="links">
|
<section xml:id="links">
|
||||||
<title>Links as First-Class Objects</title>
|
<title>Links as First-Class Objects</title>
|
||||||
|
|
||||||
<para>
|
<para>Links are an essential part of RESTful resources and allow for easy discoverability of related resources. In
|
||||||
|
Spring Data REST, a link is represented in JSON as an object with a
|
||||||
|
<code>rel</code>
|
||||||
|
and
|
||||||
|
<code>href</code>
|
||||||
|
property. These objects will appear in an array under an object's
|
||||||
|
<code>links</code>
|
||||||
|
property. These objects are meant to provide a user agent with the URLs necessary to retrieve resources related to
|
||||||
|
the current resource being accessed.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
<para>When accessing the root of a Spring Data REST application, for example, links are provided to each repository
|
||||||
|
that is exported. The user agent can then pick the link it is interested in and follow that<code>href</code>.
|
||||||
|
Issue a
|
||||||
|
<code>get</code>
|
||||||
|
in the
|
||||||
|
<code>rest-shell</code>
|
||||||
|
to see an example of links.
|
||||||
|
|
||||||
|
<programlisting><![CDATA[
|
||||||
|
http://localhost:8080:> get
|
||||||
|
> GET http://localhost:8080/
|
||||||
|
|
||||||
|
< 200 OK
|
||||||
|
< Content-Type: application/json
|
||||||
|
<
|
||||||
|
{
|
||||||
|
"links" : [ {
|
||||||
|
"rel" : "people",
|
||||||
|
"href" : "http://localhost:8080/people"
|
||||||
|
}, {
|
||||||
|
"rel" : "profile",
|
||||||
|
"href" : "http://localhost:8080/profile"
|
||||||
|
}, {
|
||||||
|
"rel" : "customer",
|
||||||
|
"href" : "http://localhost:8080/customer"
|
||||||
|
}, {
|
||||||
|
"rel" : "order",
|
||||||
|
"href" : "http://localhost:8080/order"
|
||||||
|
}, {
|
||||||
|
"rel" : "product",
|
||||||
|
"href" : "http://localhost:8080/product"
|
||||||
|
} ],
|
||||||
|
"content" : [ ]
|
||||||
|
}]]></programlisting>
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<title>Entity Relationships</title>
|
||||||
|
|
||||||
|
<para>If two entities are related to one another through a database-defined relationship, then that relationship
|
||||||
|
will appear in the JSON as a link. In JPA, one would place a
|
||||||
|
<code>@ManyToOne</code>,
|
||||||
|
<code>@OneToOne</code>, or other relationship annotation. If using Spring Data MongoDB, one would place a
|
||||||
|
<code>@DBRef</code>
|
||||||
|
annotation on a property to denote its special status as a reference to other entities. In the example project,
|
||||||
|
the
|
||||||
|
<classname>Person</classname>
|
||||||
|
class has a related set of
|
||||||
|
<classname>Person</classname>
|
||||||
|
entities in the
|
||||||
|
<code>siblings</code>
|
||||||
|
property. If you
|
||||||
|
<code>get</code>
|
||||||
|
the resource of a
|
||||||
|
<classname>Person</classname>
|
||||||
|
you will see, in the
|
||||||
|
<code>siblings</code>
|
||||||
|
property, the link to follow to get the related
|
||||||
|
<classname>Person</classname>s.
|
||||||
|
|
||||||
|
<programlisting><![CDATA[
|
||||||
|
http://localhost:8080:> get people/1
|
||||||
|
> GET http://localhost:8080/people/1
|
||||||
|
|
||||||
|
< 200 OK
|
||||||
|
< Content-Type: application/json
|
||||||
|
<
|
||||||
|
{
|
||||||
|
"firstName" : "Billy Bob",
|
||||||
|
"surname" : "Thornton",
|
||||||
|
"links" : [ {
|
||||||
|
"rel" : "self",
|
||||||
|
"href" : "http://localhost:8080/people/1"
|
||||||
|
}, {
|
||||||
|
"rel" : "people.person.father",
|
||||||
|
"href" : "http://localhost:8080/people/1/father"
|
||||||
|
}, {
|
||||||
|
"rel" : "people.person.siblings",
|
||||||
|
"href" : "http://localhost:8080/people/1/siblings"
|
||||||
|
} ]
|
||||||
|
}]]></programlisting>
|
||||||
|
</para>
|
||||||
|
</section>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section xml:id="mapping">
|
<section xml:id="mapping">
|
||||||
@@ -26,8 +119,107 @@
|
|||||||
content-type.
|
content-type.
|
||||||
</para>
|
</para>
|
||||||
</footnote>
|
</footnote>
|
||||||
|
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
<para>Sometimes the behavior of the Spring Data REST's ObjectMapper, which has been specially configured to use
|
||||||
|
intelligent serializers that can turn domain objects into links and back again, may not handle your domain model
|
||||||
|
correctly. There are so many ways one can structure your data that you may find your own domain model isn't being
|
||||||
|
translated to JSON correctly. It's also sometimes not practical in these cases to try and support a complex domain
|
||||||
|
model in a generic way. Sometimes, depending on the complexity, it's not even possible to offer a generic
|
||||||
|
solution.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<title>Adding custom (de)serializers to Jackson's ObjectMapper</title>
|
||||||
|
|
||||||
|
<para>To accommodate the largest percentage of use cases, Spring Data REST tries very hard to render your
|
||||||
|
object graph correctly. It will try and serialize unmanaged beans as normal POJOs and it will try and create
|
||||||
|
links to managed beans where that's necessary. But if your domain model doesn't easily lend itself to reading or
|
||||||
|
writing plain JSON, you may want to configure Jackson's ObjectMapper with your own custom type mappings and
|
||||||
|
(de)serializers.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<title>Abstract class registration</title>
|
||||||
|
|
||||||
|
<para>One key configuration point you might need to hook into is when you're using an abstract class (or an
|
||||||
|
interface) in your domain model. Jackson won't know by default what implementation to create for an interface.
|
||||||
|
Take the following example:
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<programlisting language="java"><![CDATA[@Entity
|
||||||
|
public class MyEntity {
|
||||||
|
@OneToMany
|
||||||
|
private List<MyInterface> interfaces;
|
||||||
|
}]]></programlisting>
|
||||||
|
|
||||||
|
<para>In a default configuration, Jackson has no idea what class to instantiate when POSTing new data to the
|
||||||
|
exporter. This is something you'll need to tell Jackson either through an annotation, or, more cleanly, by
|
||||||
|
registering a type mapping using a
|
||||||
|
<classname>Module</classname>.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>To add your own Jackson configuration to the
|
||||||
|
<classname>ObjectMapper</classname>
|
||||||
|
used by Spring Data REST, override the
|
||||||
|
<code>configureJacksonObjectMapper</code>
|
||||||
|
method. That method will be passed an
|
||||||
|
<classname>ObjectMapper</classname>
|
||||||
|
instance that has a special module to handle serializing and deserializing
|
||||||
|
<classname>PersistentEntity</classname>s. You can register your own modules as well, like in the following
|
||||||
|
example.
|
||||||
|
|
||||||
|
<programlisting language="java"><![CDATA[
|
||||||
|
@Override protected void configureJacksonObjectMapper(ObjectMapper objectMapper) {
|
||||||
|
objectMapper.registerModule(new SimpleModule("MyCustomModule"){
|
||||||
|
@Override public void setupModule(SetupContext context) {
|
||||||
|
context.addAbstractTypeResolver(
|
||||||
|
new SimpleAbstractTypeResolver().addMapping(MyInterface.class,
|
||||||
|
MyInterfaceImpl.class)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}]]></programlisting>
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>Once you have access to the
|
||||||
|
<classname>SetupContext</classname>
|
||||||
|
object in your
|
||||||
|
<classname>Module</classname>, you can do all sorts of cool things to
|
||||||
|
configure Jacskon's JSON mapping. You can read more about how
|
||||||
|
<classname>Module</classname>s work on Jackson's wiki:
|
||||||
|
<link xlink:href="http://wiki.fasterxml.com/JacksonFeatureModules">
|
||||||
|
http://wiki.fasterxml.com/JacksonFeatureModules
|
||||||
|
</link>
|
||||||
|
</para>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<title>Adding custom serializers for domain types</title>
|
||||||
|
|
||||||
|
<para>If you want to (de)serialize a domain type in a special way, you can register your own implementations
|
||||||
|
with Jackson's
|
||||||
|
<classname>ObjectMapper</classname>
|
||||||
|
and the Spring Data REST exporter will transparently handle those domain objects correctly. To add
|
||||||
|
serializers, from your
|
||||||
|
<code>setupModule</code>
|
||||||
|
method implementation, do something like the following:
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<programlisting language="java"><![CDATA[
|
||||||
|
@Override public void setupModule(SetupContext context) {
|
||||||
|
SimpleSerializers serializers = new SimpleSerializers();
|
||||||
|
SimpleDeserializers deserializers = new SimpleDeserializers();
|
||||||
|
|
||||||
|
serializers.addSerializer(MyEntity.class, new MyEntitySerializer());
|
||||||
|
deserializers.addDeserializer(MyEntity.class, new MyEntityDeserializer());
|
||||||
|
|
||||||
|
context.addSerializers(serializers);
|
||||||
|
context.addDeserializers(deserializers);
|
||||||
|
}]]></programlisting>
|
||||||
|
</section>
|
||||||
|
</section>
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
</chapter>
|
</chapter>
|
||||||
619
src/reference/docbook/rest-shell.xml
Normal file
619
src/reference/docbook/rest-shell.xml
Normal file
@@ -0,0 +1,619 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<chapter xml:id="intro-chapter"
|
||||||
|
xmlns="http://docbook.org/ns/docbook"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://docbook.org/ns/docbook http://www.oasis-open.org/docbook/xml/5.0/xsd/docbook.xsd
|
||||||
|
http://www.w3.org/1999/xlink http://www.oasis-open.org/docbook/xml/5.0/xsd/xlink.xsd">
|
||||||
|
|
||||||
|
<title>Using the
|
||||||
|
<command>rest-shell</command>
|
||||||
|
</title>
|
||||||
|
|
||||||
|
<para>The
|
||||||
|
<link xlink:href="https://github.com/SpringSource/rest-shell">
|
||||||
|
<command>rest-shell</command>
|
||||||
|
</link>
|
||||||
|
is a command-line shell that aims to make writing REST-based applications easier. It is based on spring-shell and
|
||||||
|
integrated with Spring HATEOAS in such a way that REST resources that output JSON compliant with Spring HATEOAS
|
||||||
|
can be discovered by the shell and interactions with the REST resources become much easier than by manipulating
|
||||||
|
the URLs in bash using a tool like
|
||||||
|
<command>curl</command>.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>The rest-shell provides a number of useful commands for discovering and interacting with REST resources. For
|
||||||
|
example discover will discover what resources are available and print out an easily-readable table of rels and
|
||||||
|
URIs that relate to those resources. Once these resources have been discovered, the rel of those URIs can be used
|
||||||
|
in place of the URI itself in most operations, thus cutting down on the amount of typing needed to issue HTTP
|
||||||
|
requests to your REST resources.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<title>Installing the
|
||||||
|
<command>rest-shell</command>
|
||||||
|
</title>
|
||||||
|
|
||||||
|
<para>If you're using Mac OS X and Homebrew, then installation is super easy:</para>
|
||||||
|
|
||||||
|
<programlisting><![CDATA[brew install rest-shell]]></programlisting>
|
||||||
|
|
||||||
|
<para>Other platforms are simple as well: just download the archive from the GitHub page and unzip it to a
|
||||||
|
location on your local hard drive.
|
||||||
|
</para>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<title>Discovering resources</title>
|
||||||
|
|
||||||
|
<para>The rest-shell is aimed at making it easier to interact with REST resources by managing the session baseUri
|
||||||
|
much like a directory in a filesystem. Whenever resources are discovered, you can then follow to a new baseUri,
|
||||||
|
which means you can then use relative URIs. Here's an example of discovering resources, then following a link by
|
||||||
|
referencing its rel value, and then using a relative URI to access resources under that new baseUri:
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<programlisting><![CDATA[http://localhost:8080:> discover
|
||||||
|
rel href
|
||||||
|
========================================================
|
||||||
|
address http://localhost:8080/address
|
||||||
|
family http://localhost:8080/family
|
||||||
|
people http://localhost:8080/person
|
||||||
|
profile http://localhost:8080/profile
|
||||||
|
|
||||||
|
http://localhost:8080:> follow people
|
||||||
|
http://localhost:8080/person:> list
|
||||||
|
rel href
|
||||||
|
===================================================
|
||||||
|
people.Person http://localhost:8080/person/1
|
||||||
|
people.Person http://localhost:8080/person/2
|
||||||
|
people.search http://localhost:8080/person/search
|
||||||
|
|
||||||
|
http://localhost:8080/person:> get 1
|
||||||
|
> GET http://localhost:8080/person/1
|
||||||
|
|
||||||
|
< 200 OK
|
||||||
|
< ETag: "2"
|
||||||
|
< Content-Type: application/json
|
||||||
|
<
|
||||||
|
{
|
||||||
|
"links" : [ {
|
||||||
|
"rel" : "self",
|
||||||
|
"href" : "http://localhost:8080/person/1"
|
||||||
|
}, {
|
||||||
|
"rel" : "peeps.Person.profiles",
|
||||||
|
"href" : "http://localhost:8080/person/1/profiles"
|
||||||
|
}, {
|
||||||
|
"rel" : "peeps.Person.addresses",
|
||||||
|
"href" : "http://localhost:8080/person/1/addresses"
|
||||||
|
} ],
|
||||||
|
"name" : "John Doe"
|
||||||
|
}]]></programlisting>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
<emphasis>NOTE: If you want tab completion of discovered rels, just use the --rel flag.</emphasis>
|
||||||
|
</para>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<title>Creating new resources</title>
|
||||||
|
|
||||||
|
<para>The rest-shell can do basic parsing of JSON data within the shell (though there are some limitations due to
|
||||||
|
the nature of the command line parsing being sensitive to whitespace). This makes it easy to create new
|
||||||
|
resources
|
||||||
|
by including JSON data directly in the shell:
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<programlisting><![CDATA[http://localhost:8080/person:> post --data "{name: 'John Doe'}"
|
||||||
|
> POST http://localhost:8080/person/
|
||||||
|
|
||||||
|
< 201 CREATED
|
||||||
|
< Location: http://localhost:8080/person/8
|
||||||
|
< Content-Length: 0
|
||||||
|
<
|
||||||
|
|
||||||
|
http://localhost:8080/person:> get 8
|
||||||
|
> GET http://localhost:8080/person/8
|
||||||
|
|
||||||
|
< 200 OK
|
||||||
|
< ETag: "0"
|
||||||
|
< Content-Type: application/json
|
||||||
|
<
|
||||||
|
{
|
||||||
|
"links" : [ {
|
||||||
|
"rel" : "self",
|
||||||
|
"href" : "http://localhost:8080/person/8"
|
||||||
|
}, {
|
||||||
|
"rel" : "people.Person.addresses",
|
||||||
|
"href" : "http://localhost:8080/person/8/addresses"
|
||||||
|
}, {
|
||||||
|
"rel" : "people.Person.profiles",
|
||||||
|
"href" : "http://localhost:8080/person/8/profiles"
|
||||||
|
} ],
|
||||||
|
"name" : "John Doe"
|
||||||
|
}]]></programlisting>
|
||||||
|
|
||||||
|
<para>If your needs of representing JSON get more complicated than what the spring-shell interface can handle, you
|
||||||
|
can create a directory somewhere with .json files in it, one file per entitiy, and use the --from option to the
|
||||||
|
post command. This will walk the directory and make a POST request for each .json file found.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<programlisting><![CDATA[http://localhost:8080/person:> post --from work/people_to_load
|
||||||
|
128 items uploaded to the server using POST.
|
||||||
|
http://localhost:8080/person:>]]></programlisting>
|
||||||
|
|
||||||
|
<para>You can also reference a specific file rather than an entire directory.</para>
|
||||||
|
|
||||||
|
<programlisting><![CDATA[http://localhost:8080/person:> post --from work/people_to_load/someone.json
|
||||||
|
1 items uploaded to the server using POST.
|
||||||
|
http://localhost:8080/person:>]]></programlisting>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<title>Passing query parameters</title>
|
||||||
|
|
||||||
|
<para>If you're calling URLs that require query parameters, you'll need to pass those as a JSON-like fragment in
|
||||||
|
the --params parameter to the get and list commands. Here's an example of calling a URL that expects parameter
|
||||||
|
input:
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<programlisting><![CDATA[http://localhost:8080/person:> get search/byName --params "{name: 'John Doe'}"]]>
|
||||||
|
</programlisting>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<title>Outputing results to a file</title>
|
||||||
|
|
||||||
|
<para>It's not always desirable to output the results of an HTTP request to the screen. It's handy for debugging
|
||||||
|
but
|
||||||
|
sometimes you want to save the results of a request because they're not easily reproducible or any number of
|
||||||
|
other
|
||||||
|
equally valid reasons. All the HTTP commands take an --output parameter that writes the results of an HTTP
|
||||||
|
operation to the given file. For example, to output the above search to a file:
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<programlisting><![CDATA[http://localhost:8080/person:> get search/byName --params "{name: 'John Doe'}" --output by_name.txt >> by_name.txt
|
||||||
|
http://localhost:8080/person:>]]></programlisting>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<title>Sending complex JSON</title>
|
||||||
|
|
||||||
|
<para>Because the rest-shell uses the spring-shell underneath, there are limitations on the format of the JSON
|
||||||
|
data
|
||||||
|
you can enter directly into the command line. If your JSON is too complex for the simplistic limitations of the
|
||||||
|
shell --data parameter, you can simply load the JSON from a file or from all the files in a directory.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>When doing a post or put, you can optionally pass the --from parameter. The value of this parameter should
|
||||||
|
either be a file or a directory. If the value is a directory, the shell will read each file that ends with .json
|
||||||
|
and make a POST or PUT with the contents of that file. If the parameter is a file, then the rest-shell will
|
||||||
|
simpy
|
||||||
|
load that file and POST/PUT that data in that individual file.
|
||||||
|
</para>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<title>Shelling out to bash</title>
|
||||||
|
|
||||||
|
<para>One of the nice things about spring-shell is that you can directly shell out commands to the underlying
|
||||||
|
terminal shell. This is useful for doing things like load a JSON file in an editor. For instance, assume I have
|
||||||
|
the Sublime Text 2 command subl in my path. I can then load a JSON file for editing from the rest-shell like
|
||||||
|
this:
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<programlisting><![CDATA[http://localhost:8080/person:> ! subl test.json
|
||||||
|
http://localhost:8080/person:>]]></programlisting>
|
||||||
|
|
||||||
|
<para>I then edit the file as I wish. When I'm ready to POST that data to the server, I can do so using the --from
|
||||||
|
parameter:
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<programlisting><![CDATA[http://localhost:8080/person:> post --from test.json
|
||||||
|
1 items uploaded to the server using POST.
|
||||||
|
http://localhost:8080/person:>]]></programlisting>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<title>Setting context variables</title>
|
||||||
|
|
||||||
|
<para>Starting with rest-shell version 1.1, you can also work with context variables during your shell session.
|
||||||
|
This
|
||||||
|
is useful for saving settings you might reference often. The rest-shell now integrates Spring Expression
|
||||||
|
Language
|
||||||
|
support, so these context variables are usable in expressions within the shell.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
|
||||||
|
<programlisting><![CDATA[http://localhost:8080/person:> var set --name specialUri --value http://longdomainname.com/api
|
||||||
|
http://localhost:8080/person:> var get --name specialUri
|
||||||
|
http://longdomainname.com/api
|
||||||
|
http://localhost:8080/person:> var list
|
||||||
|
{
|
||||||
|
"responseHeaders" : {
|
||||||
|
... HTTP headers from last request
|
||||||
|
},
|
||||||
|
"responseBody" : {
|
||||||
|
... Body from the last request
|
||||||
|
},
|
||||||
|
"specialUri" : "http://longdomainname.com/api",
|
||||||
|
"requestUrl" : ... URL from the last request,
|
||||||
|
"env" : {
|
||||||
|
... System properties and environment variables
|
||||||
|
}
|
||||||
|
}]]></programlisting>
|
||||||
|
|
||||||
|
<para>The variables are accessible from SpEL expressions which are valid in a number of different contexts, most
|
||||||
|
importantly in the path argument to the HTTP and discover commands, and in the data argument to the put and post
|
||||||
|
commands.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>Since the rest-shell is aware of environment variables and system properties, you can incorporate external
|
||||||
|
parameters into your interaction with the shell. For example, to externally define a baseUri, you could set a
|
||||||
|
system property before invoking the shell. The shell will incorporate anything defined in the JAVA_OPTS
|
||||||
|
environment variable, so you could parameterize your interaction with a REST service.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<programlisting><![CDATA[JAVA_OPTS="-DbaseUri=http://mylongdomain.com/api" rest-shell
|
||||||
|
|
||||||
|
http://localhost:8080:> discover #{env.baseUri}
|
||||||
|
rel href
|
||||||
|
=================================================================
|
||||||
|
... resources for this URL
|
||||||
|
http://mylongdomain.com/api:>]]></programlisting>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<title>Per-user shell initialization</title>
|
||||||
|
|
||||||
|
<para>The rest-shell supports a "dotrc" type of initialization by reading in all files found in the
|
||||||
|
$HOME/.rest-shell/ directory and assuming they have shell commands in them. The rest-shell will execute these
|
||||||
|
commands on startup. This makes it easy to set variables for commonly-used URIs or possibly set a baseUri.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<programlisting><![CDATA[echo "var set --name svcuri --value http://api.myservice.com/v1" > ~/.rest-shell/00-vars
|
||||||
|
echo "discover #{svcuri}" > ~/.rest-shell/01-baseUri
|
||||||
|
|
||||||
|
> rest-shell
|
||||||
|
|
||||||
|
INFO: No resources found...
|
||||||
|
INFO: Base URI set to 'http://api.myservice.com/v1'
|
||||||
|
|
||||||
|
___ ___ __ _____ __ _ _ _ _ __
|
||||||
|
| _ \ __/' _/_ _/' _/| || | / / | \ \
|
||||||
|
| v / _|`._`. | | `._`.| >< | / / / > >
|
||||||
|
|_|_\___|___/ |_| |___/|_||_| |_/_/ /_/
|
||||||
|
1.2.1.RELEASE
|
||||||
|
|
||||||
|
Welcome to the REST shell. For assistance hit TAB or type "help".
|
||||||
|
http://api.myservice.com/v1:>]]></programlisting>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<title>SSL Certificate Validation</title>
|
||||||
|
|
||||||
|
<para>If you generate a self-signed certificate for your server, by default the rest-shell will complain and
|
||||||
|
refuse
|
||||||
|
to connect. This is the default behavior of RestTemplate. To turn off certificate and hostname checking, use the
|
||||||
|
ssl validate --enabled false command.
|
||||||
|
</para>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<title>HTTP Basic authentication</title>
|
||||||
|
|
||||||
|
<para>There is also a convenience command for setting an HTTP Basic authentication header. Use auth basic
|
||||||
|
--username
|
||||||
|
user --pasword passwd to set a username and password to base64 encode and place into the Authorization header
|
||||||
|
that
|
||||||
|
will be part of the current session's headers.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>You can clear the authentication by using the auth clear command or by removing the Authorization header
|
||||||
|
using
|
||||||
|
the headers clear command.
|
||||||
|
</para>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<title>Commands</title>
|
||||||
|
|
||||||
|
<para>The rest-shell provides the following commands:</para>
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<caption>rest-shell commands</caption>
|
||||||
|
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Command</th>
|
||||||
|
<th>Description</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<cmdsynopsis>
|
||||||
|
<command>baseUri</command>
|
||||||
|
<arg choice="req">
|
||||||
|
<replaceable>uri</replaceable>
|
||||||
|
</arg>
|
||||||
|
</cmdsynopsis>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<para>Set the base URI used for this point forward in the session. Relative URIs will be calculated relative
|
||||||
|
to this setting.
|
||||||
|
</para>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<cmdsynopsis>
|
||||||
|
<command>discover</command>
|
||||||
|
<group>
|
||||||
|
<arg>--rel
|
||||||
|
<replaceable>rel</replaceable>
|
||||||
|
</arg>
|
||||||
|
<arg>
|
||||||
|
<replaceable>path</replaceable>
|
||||||
|
</arg>
|
||||||
|
</group>
|
||||||
|
</cmdsynopsis>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<para>Find out what resources are available at the given URI. If no URI is given, use the baseUri.
|
||||||
|
</para>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<cmdsynopsis>
|
||||||
|
<command>follow</command>
|
||||||
|
<group>
|
||||||
|
<arg>--rel
|
||||||
|
<replaceable>rel</replaceable>
|
||||||
|
</arg>
|
||||||
|
<arg>
|
||||||
|
<replaceable>path</replaceable>
|
||||||
|
</arg>
|
||||||
|
</group>
|
||||||
|
</cmdsynopsis>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<para>Set the baseUri to the URI assigned to this given rel or path but do not discover resources.
|
||||||
|
</para>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<cmdsynopsis>
|
||||||
|
<command>list</command>
|
||||||
|
<group>
|
||||||
|
<arg>--rel
|
||||||
|
<replaceable>rel</replaceable>
|
||||||
|
</arg>
|
||||||
|
<arg>
|
||||||
|
<replaceable>path</replaceable>
|
||||||
|
</arg>
|
||||||
|
</group>
|
||||||
|
<arg>--params
|
||||||
|
<replaceable>JSON</replaceable>
|
||||||
|
</arg>
|
||||||
|
</cmdsynopsis>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<para>Find out what resources are available at the given URI.
|
||||||
|
</para>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<cmdsynopsis>
|
||||||
|
<command>headers set</command>
|
||||||
|
<arg choice="req">--name
|
||||||
|
<replaceable>name</replaceable>
|
||||||
|
</arg>
|
||||||
|
<arg choice="req">--value
|
||||||
|
<replaceable>value</replaceable>
|
||||||
|
</arg>
|
||||||
|
</cmdsynopsis>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<para>Set an HTTP header for use from this point forward in the session.</para>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<cmdsynopsis>
|
||||||
|
<command>headers clear</command>
|
||||||
|
</cmdsynopsis>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<para>Clear all HTTP headers set during this session.</para>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<cmdsynopsis>
|
||||||
|
<command>headers list</command>
|
||||||
|
</cmdsynopsis>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<para>Print out the currently-set HTTP headers for this session.</para>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<cmdsynopsis>
|
||||||
|
<command>history list</command>
|
||||||
|
</cmdsynopsis>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<para>List the URIs previously set as baseUris during this session.</para>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<cmdsynopsis>
|
||||||
|
<command>history go</command>
|
||||||
|
<arg>
|
||||||
|
<replaceable>num</replaceable>
|
||||||
|
</arg>
|
||||||
|
</cmdsynopsis>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<para>Jump to a URI by pulling one from the history.</para>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<cmdsynopsis>
|
||||||
|
<command>var clear</command>
|
||||||
|
</cmdsynopsis>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<para>Clear this shell's variable context.</para>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<cmdsynopsis>
|
||||||
|
<command>var get</command>
|
||||||
|
<arg>--name
|
||||||
|
<replaceable>name</replaceable>
|
||||||
|
</arg>
|
||||||
|
<arg>--value
|
||||||
|
<replaceable>expression</replaceable>
|
||||||
|
</arg>
|
||||||
|
</cmdsynopsis>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<para>Get a variable from this shell's context by name or evaluate a shell expression.</para>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<cmdsynopsis>
|
||||||
|
<command>var list</command>
|
||||||
|
</cmdsynopsis>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<para>List variables currently set in this shell's context.</para>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<cmdsynopsis>
|
||||||
|
<command>var set</command>
|
||||||
|
</cmdsynopsis>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<para>Set a variable in this shell's context.</para>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<cmdsynopsis>
|
||||||
|
<command>up</command>
|
||||||
|
</cmdsynopsis>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<para>Traverse one level up in the URL hierarchy.</para>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<cmdsynopsis>
|
||||||
|
<command>get</command>
|
||||||
|
<group>
|
||||||
|
<arg>--rel
|
||||||
|
<replaceable>rel</replaceable>
|
||||||
|
</arg>
|
||||||
|
<arg>
|
||||||
|
<replaceable>path</replaceable>
|
||||||
|
</arg>
|
||||||
|
</group>
|
||||||
|
<arg>--follow true | false</arg>
|
||||||
|
<arg>--params
|
||||||
|
<replaceable>JSON</replaceable>
|
||||||
|
</arg>
|
||||||
|
<arg>--output
|
||||||
|
<replaceable>filename</replaceable>
|
||||||
|
</arg>
|
||||||
|
</cmdsynopsis>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<para>HTTP GET from the given path. If
|
||||||
|
<code>--follow true</code>
|
||||||
|
is set, then follow any redirects automatically. If
|
||||||
|
<code>--output filename</code>
|
||||||
|
is set, output the the response into the given file.
|
||||||
|
</para>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<cmdsynopsis>
|
||||||
|
<command>post</command>
|
||||||
|
</cmdsynopsis>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<para>HTTP POST to the given path, passing JSON given in the --data parameter.</para>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<cmdsynopsis>
|
||||||
|
<command>put</command>
|
||||||
|
</cmdsynopsis>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<para>HTTP PUT to the given path, passing JSON given in the --data parameter.</para>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<cmdsynopsis>
|
||||||
|
<command>delete</command>
|
||||||
|
</cmdsynopsis>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<para>HTTP DELETE to the given path.</para>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<cmdsynopsis>
|
||||||
|
<command>auth basic</command>
|
||||||
|
</cmdsynopsis>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<para>Set an HTTP Basic authentication token for use in this session.</para>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<cmdsynopsis>
|
||||||
|
<command>auth clear</command>
|
||||||
|
</cmdsynopsis>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<para>Clear the Authorization header currently in use.</para>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<cmdsynopsis>
|
||||||
|
<command>ssl validate</command>
|
||||||
|
</cmdsynopsis>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<para>Disable certificate checking to work with self-signed certificates.</para>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
|
||||||
|
</chapter>
|
||||||
28
src/reference/docbook/validation.xml
Normal file
28
src/reference/docbook/validation.xml
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<chapter xml:id="validation-chapter"
|
||||||
|
xmlns="http://docbook.org/ns/docbook"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://docbook.org/ns/docbook http://www.oasis-open.org/docbook/xml/5.0/xsd/docbook.xsd">
|
||||||
|
|
||||||
|
<title>Validation</title>
|
||||||
|
|
||||||
|
<para>Integrating validation into Spring Data REST is as easy as registering your
|
||||||
|
<classname>Validator</classname>
|
||||||
|
implementation with the
|
||||||
|
<classname>ValidatingRepositoryEventListener</classname>, whose job it is to trigger
|
||||||
|
validators whenever certain events happen inside Spring Data REST.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>To add your validators, override the
|
||||||
|
<code>configureValidatingRepositoryEventListener</code>
|
||||||
|
method and call the
|
||||||
|
<code>addValidator</code>
|
||||||
|
method:
|
||||||
|
|
||||||
|
<programlisting language="java"><![CDATA[
|
||||||
|
@Override protected void configureValidatingRepositoryEventListener(ValidatingRepositoryEventListener v) {
|
||||||
|
v.addValidator("beforeSave", new BeforeSaveValidator());
|
||||||
|
}]]></programlisting>
|
||||||
|
</para>
|
||||||
|
|
||||||
|
</chapter>
|
||||||
Reference in New Issue
Block a user