juneau-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jamesbog...@apache.org
Subject [1/5] incubator-juneau-website git commit: Break out about page into separate components.
Date Mon, 16 Oct 2017 20:07:16 GMT
Repository: incubator-juneau-website
Updated Branches:
  refs/heads/asf-site 5d9adf951 -> 38b4b4437


http://git-wip-us.apache.org/repos/asf/incubator-juneau-website/blob/e87529b2/content/rest-server.html
----------------------------------------------------------------------
diff --git a/content/rest-server.html b/content/rest-server.html
new file mode 100644
index 0000000..aa1965d
--- /dev/null
+++ b/content/rest-server.html
@@ -0,0 +1,748 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+	@import url("styles/juneau-code.css");
+	@import url("styles/juneau-doc.css");
+</style>
+</head>
+<body>
+
+	<!-- =======================================================================================================
-->
+	<!-- === JUNEAU-REST-SERVER ================================================================================
-->
+	<!-- =======================================================================================================
-->
+	
+	<h5 class='toc' id='juneau-rest-server'>juneau-rest-server</h5>
+	<div>
+		<h6 class='figure'>Maven Dependency</h6>
+		<p class='bcode' style='width:500px;'>
+	<xt>&lt;dependency&gt;</xt>
+		<xt>&lt;groupId&gt;</xt>org.apache.juneau<xt>&lt;/groupId&gt;</xt>
+		<xt>&lt;artifactId&gt;</xt>juneau-rest-server<xt>&lt;/artifactId&gt;</xt>
+		<xt>&lt;version&gt;</xt>6.4.0-incubating<xt>&lt;/version&gt;</xt>
+	<xt>&lt;/dependency&gt;</xt>
+		</p>	
+	
+		<h6 class='figure'>Java Library</h6>
+		<p class='bcode' style='width:500px;'>
+	juneau-rest-server-6.4.0-incubating.jar 
+		</p>	
+	
+		<h6 class='figure'>OSGi Module</h6>
+		<p class='bcode' style='width:500px;'>
+	org.apache.juneau.rest.server_6.4.0-incubating.jar 
+		</p>	
+
+		<p>
+			The REST server API builds upon the <code>SerializerGroup</code> and <code>ParserGroup</code>
classes 
+			to provide annotated REST servlets that automatically negotiate the HTTP media types for
you.
+			<br>Developers simply work with requests, responses, headers, path variables, query
parameters, and form data as POJOs.
+			<br>It allows you to create sophisticated REST interfaces using tiny amounts of
code.
+		</p>
+		<p>
+			The end goal is to provide simple and flexible yet sophisticated REST interfaces that
allow POJOs to be automatically represented as 
+			different content types depending on whatever the particular need: 
+		</p>
+		<ul class='spaced-list'>
+			<li>HTML for viewing POJOs in easy-to-read format in a browser.
+			<li>JSON for interacting through Javascript.
+			<li>XML for interacting with other applications.
+			<li>RDF for interacting with triple stores.
+			<li>URL-Encoding for interacting through HTML forms.
+			<li>MessagePack for efficiently transmitting large amounts of data.
+		</ul>
+		<p>
+			A simple example that supports all languages:
+		</p>
+		<p class='bcode'>
+	<ja>@RestResource</ja>(
+		path=<js>"/systemProperties"</js>,
+		title=<js>"System properties resource"</js>
+	)
+	<jk>public class</jk> SystemPropertiesResource <jk>extends</jk>
RestServletDefault {
+	
+		<ja>@RestMethod</ja>(name=<jsf>GET</jsf>, path=<js>"/"</js>)
+		<jk>public</jk> Map getSystemProperties(<ja>@Query</ja>(<js>"sort"</js>)
<jk>boolean</jk> sort) <jk>throws</jk> Throwable {
+			<jk>if</jk> (sort)
+				<jk>return new</jk> TreeMap(System.<jsm>getProperties</jsm>());
+			<jk>return</jk> System.<jsm>getProperties</jsm>();
+		}
+	
+		<ja>@RestMethod</ja>(name=<jsf>GET</jsf>, path=<js>"/{propertyName}"</js>)
+		<jk>public</jk> String getSystemProperty(<ja>@Path</ja> String
propertyName) <jk>throws</jk> Throwable {
+			<jk>return</jk> System.<jsm>getProperty</jsm>(propertyName);
+		}
+	
+		<ja>@RestMethod</ja>(name=<jsf>PUT</jsf>, path=<js>"/{propertyName}"</js>,
guards=AdminGuard.<jk>class</jk>)
+		<jk>public</jk> String setSystemProperty(<ja>@Path</ja> String
propertyName, <ja>@Body</ja> String value) {
+			System.<jsm>setProperty</jsm>(propertyName, value);
+			<jk>return</jk> <js>"OK"</js>;
+		}
+	
+		<ja>@RestMethod</ja>(name=<jsf>POST</jsf>, path=<js>"/"</js>,
guards=AdminGuard.<jk>class</jk>)
+		<jk>public</jk> String setSystemProperties(<ja>@Body</ja> java.util.Properties
newProperties) {
+			System.<jsm>setProperties</jsm>(newProperties);
+			<jk>return</jk> <js>"OK"</js>;
+		}
+	
+		<ja>@RestMethod</ja>(name=<jsf>DELETE</jsf>, path=<js>"/{propertyName}"</js>,
guards=AdminGuard.<jk>class</jk>)
+		<jk>public</jk> String deleteSystemProperty(<ja>@Path</ja> String
propertyName) {
+			System.<jsm>clearProperty</jsm>(propertyName);
+			<jk>return</jk> <js>"OK"</js>;
+		}
+	}
+		</p>
+		<p>
+			A more sophisticated example of the same resource using various features, including information
+			for fully populating the Swagger documentation, guards for restricting access to particular
+			methods, customizing supported content types and serialization options, adding g-zip compression,

+			and adding customized branding for the HTML views.
+		</p>
+		<p class='bcode'>
+	<ja>@RestResource</ja>(
+		path=<js>"/systemProperties"</js>,
+		title=<js>"System properties resource"</js>,
+		description=<js>"REST interface for performing CRUD operations on system properties."</js>,
+		messages=<js>"nls/SystemPropertiesResource"</js>,  <jc>// Location of
localized messages.</jc>
+		
+		<jc>// Widget used for content-type pull-down menu.</jc>		
+		widgets={
+			ContentTypeMenuItem.<jk>class</jk>
+		},
+	
+		<jc>// Links on the HTML rendition page.
+		// "request:/..." URIs are relative to the request URI.
+		// "servlet:/..." URIs are relative to the servlet URI.</jc>
+		htmldoc=<ja>@HtmlDoc</ja>(
+			
+			<jc>// Custom navigation links.</jc>
+			links={
+				<js>"up: request:/.."</js>,
+				<js>"options: servlet:/?method=OPTIONS"</js>,
+				<js>"form: servlet:/formPage"</js>,
+				<js>"$W{ContentTypeMenuItem}"</js>,
+				<js>"source: $C{Source/gitHub}/org/apache/juneau/examples/rest/SystemPropertiesResource.java"</js>
+			},
+			
+			<jc>// Custom page text in aside section.</jc>
+			aside={
+				<js>"&lt;div style='max-width:800px' class='text'&gt;"</js>,
+				<js>"	&lt;p&gt;Shows standard GET/PUT/POST/DELETE operations and use of
Swagger annotations.&lt;/p&gt;"</js>,
+				<js>"&lt;/div&gt;"</js>
+			},
+				
+			<jc>// Custom CSS styles applied to HTML view.</jc>
+			style={
+				<js>"aside {display:table-caption;}"</js>
+			}
+		),
+				
+		<jc>// Set serializer, parser, and REST context properties.</jc>
+		properties={
+			<ja>@Property</ja>(name=<jsf>SERIALIZER_quoteChar</jsf>, value=<js>"'"</js>)
+		},
+		
+		<jc>// Add compression support.</jc>
+		encoders=GzipEncoder.<jk>class</jk>,
+		
+		<jc>// Augment generated Swagger information.</jc>
+		swagger=<ja>@ResourceSwagger</ja>(
+			contact=<js>"{name:'John Smith',email:'john@smith.com'}"</js>,
+			license=<js>"{name:'Apache 2.0',url:'http://www.apache.org/licenses/LICENSE-2.0.html'}"</js>,
+			version=<js>"2.0"</js>,
+			termsOfService=<js>"You're on your own."</js>,
+			tags=<js>"[{name:'Java',description:'Java utility',externalDocs:{description:'Home
page',url:'http://juneau.apache.org'}}]"</js>,
+			externalDocs=<js>"{description:'Home page',url:'http://juneau.apache.org'}"</js>
+		)
+	)
+	<jk>public class</jk> SystemPropertiesResource <jk>extends</jk>
RestServlet {
+	
+		<ja>@RestMethod</ja>(
+			name=<jsf>GET</jsf>, path=<js>"/"</js>,
+			summary=<js>"Show all system properties"</js>,
+			description=<js>"Returns all system properties defined in the JVM."</js>,
+			
+			<jc>// Augment generated Swagger information.</jc>
+			swagger=<ja>@MethodSwagger</ja>(
+				parameters={
+					<ja>@Parameter</ja>(in=<js>"query"</js>, name=<js>"sort"</js>,
description=<js>"Sort results alphabetically."</js>, _default=<js>"false"</js>)
+				},
+				responses={
+					<ja>@Response</ja>(value=200, description=<js>"Returns a map of key/value
pairs."</js>)
+				}
+			)
+		)
+		<jk>public</jk> Map getSystemProperties(<ja>@Query</ja>(<js>"sort"</js>)
<jk>boolean</jk> sort) <jk>throws</jk> Throwable {
+			<jk>if</jk> (sort)
+				<jk>return new</jk> TreeMap(System.<jsm>getProperties</jsm>());
+			<jk>return</jk> System.<jsm>getProperties</jsm>();
+		}
+	
+		...
+	}
+		</p>
+		
+		<p>
+			In HTML, our resource looks like this:
+		</p>
+		<img class='bordered' src='images/SystemPropertiesResource.png' width="800px">
+		
+		<p>
+			When combined with the support for HTML5 beans, simple HTML forms can be constructed for
easy input and output
+			using nothing more than Java:
+		</p>
+		<p class='bcode'>
+	<jk>import static</jk> org.apache.juneau.dto.html5.HtmlBuilder.*;
+	
+	<ja>@RestMethod</ja>(
+		name=<jsf>GET</jsf>, path=<js>"/formPage"</js>,
+		summary=<js>"Form entry page"</js>,
+		description=<js>"A form post page for setting a single system property value."</js>,
+		guards=AdminGuard.<jk>class</jk>
+	)
+	<jk>public</jk> Form getFormPage() {
+		<jk>return</jk> <jsm>form</jsm>().method(<jsf>POST</jsf>).action(<js>"formPagePost"</js>).children(
+			<jsm>table</jsm>(
+				<jsm>tr</jsm>(
+					<jsm>th</jsm>(<js>"Set system property"</js>).colspan(2)
+				),
+				<jsm>tr</jsm>(
+					<jsm>td</jsm>(<js>"Name: "</js>), <jsm>td</jsm>(<jsm>input</jsm>(<js>"text"</js>).name(<js>"name"</js>))
+				),
+				<jsm>tr</jsm>(
+					<jsm>td</jsm>(<js>"Value: "</js>), <jsm>td</jsm>(<jsm>input</jsm>(<js>"text"</js>).name(<js>"value"</js>))
+				)
+			),
+			<jsm>button</jsm>(<js>"submit"</js>,<js>"Click me!"</js>).<jsm>style</jsm>(<js>"float:right"</js>)
+		);
+	}
+
+	<ja>@RestMethod</ja>(
+		name=<jsf>POST</jsf>, path=<js>"/formPagePost"</js>, 
+		description=<js>"Accepts a simple form post of a system property name/value pair."</js>,
+		guards=AdminGuard.<jk>class</jk>
+	)
+	<jk>public</jk> Redirect formPagePost(<ja>@FormData</ja>(<js>"name"</js>)
String name, <ja>@FormData</ja>(<js>"value"</js>) String value) {
+		System.<jsm>setProperty</jsm>(name, value);
+		<jk>return new</jk> Redirect(<js>"servlet:/"</js>);  <jc>//
Redirect to the servlet top page.</jc>
+	}
+		</p>	
+		<img class='bordered' src='images/SystemPropertiesForm.png' width="800px">
+		<p>
+			The REST API is built on top of Servlets, making them easy to deploy in any JEE environment.
 
+		</p>
+		<p>
+			REST Java methods can return any of the following objects:  
+			<br>POJOs, <code>Readers</code>, <code>InputStreams</code>,
<code>ZipFiles</code>, <code>Redirects</code>, <code>Streamables</code>,
and <code>Writables</code>.
+		</p>
+		<p>
+			Or add your own handlers for other types.  
+		</p>
+		<p>
+			REST Java methods can be passed any of the following objects in any order:
+		</p>
+		<ul class='spaced-list'>
+			<li>Low-level request/response objects:
+				<br><code>HttpServletRequest</code>, <code>HttpServletResponse</code>,
<code>RestRequest</code>, <code>RestResponse</code>.
+			<li>Intermediate-level objects:  
+				<br><code>RequestHeaders</code>, <code>RequestQuery</code>,
<code>RequestFormData</code>, <code>RequestPathMatch</code>, <code>RequestBody</code>.
+			<li>All RFC 2616 request header objects:  
+				<br><code>Accept</code>, <code>AcceptLanguage</code>, <code>AcceptEncoding</code>...
+			<li>Annotated parameters:  
+				<br><ja>@Header</ja>, <ja>@Query</ja>, <ja>@FormData</ja>,
<ja>@Path</ja>, <ja>@PathRemainder</ja>, <ja>@Body</ja>.
 
+			<li>Other objects:  
+				<br><code>Locale</code>, <code>ResourceBundle</code>, <code>MessageBundle</code>,
<code>InputStream</code>, <code>OutputStream</code>, <code>Reader</code>,
<code>Writer</code>...
+			<li>User-defined parameter types.
+		</ul>
+		<p>
+			It's up to you how you want to define your REST methods. 
+			As a general rule, there are 3 broad approaches typically used:
+		</p>
+		
+		<h5 class='topic'>Methodology #1 - Annotated parameters</h5>	
+		<p>
+			This approach uses annotated parameters for retrieving input from the request.
+		</p>
+		<p class='bcode'>
+	<ja>@RestMethod</ja>(name=<jsf>GET</jsf>, path=<js>"/example1/{p1}/{p2}/{p3}/*"</js>)
+	<jk>public</jk> String example1(
+			<ja>@Method</ja> String method,                  <jc>// HTTP method.</jc>
+			<ja>@Path</ja> String p1,                        <jc>// Path variables.</jc>
+			<ja>@Path</ja> <jk>int</jk> p2,
+			<ja>@Path</ja> UUID p3,
+			<ja>@Query</ja>(<js>"q1"</js>) <jk>int</jk> q1,  
                 <jc>// Query parameters.</jc>
+			<ja>@Query</ja>(<js>"q2"</js>) String q2,
+			<ja>@Query</ja>(<js>"q3"</js>) UUID q3,
+			<ja>@PathRemainder</ja> String remainder,        <jc>// Path remainder
after pattern match.</jc>
+			<ja>@Header</ja>(<js>"Accept-Language"</js>) String lang, <jc>//
Headers.</jc>
+			<ja>@Header</ja>(<js>"Accept"</js>) String accept,
+			<ja>@Header</ja>(<js>"DNT"</js>) <jk>int</jk> doNotTrack
+		) {
+
+		<jc>// Send back a simple String response</jc>
+		String output = String.<jsm>format</jsm>(
+				<js>"method=%s, p1=%s, p2=%d, p3=%s, remainder=%s, q1=%d, q2=%s, q3=%s, lang=%s,
accept=%s, dnt=%d"</js>,
+				method, p1, p2, p3, remainder, q1, q2, q3, lang, accept, doNotTrack);
+		<jk>return</jk> output;
+	}
+		</p>	
+		
+		<h5 class='topic'>Methodology #2 - Low-level request/response objects</h5>

+		<p>
+			This approach uses low-level request/response objects to perform the same as above.
+		</p>
+		<p class='bcode'>
+	<ja>@RestMethod</ja>(name=<jsf>GET</jsf>, path=<js>"/example2/{p1}/{p2}/{p3}/*"</js>)
+	<jk>public</jk> String example2(
+			RestRequest req,          <jc>// A direct subclass of HttpServletRequest.</jc>
+			RestResponse res          <jc>// A direct subclass of HttpServletResponse.</jc>
+		) {
+		
+		<jc>// HTTP method.</jc>
+		String method = req.getMethod();
+
+		<jc>// Path variables.</jc>
+		RequestPathMatch path = req.getPathMatch();
+		String p1 = path.get(<js>"p1"</js>, String.<jk>class</jk>);
+		<jk>int</jk> p2 = path.get(<js>"p2"</js>, <jk>int</jk>.<jk>class</jk>);
+		UUID p3 = path.get(<js>"p3"</js>, UUID.<jk>class</jk>);
+
+		<jc>// Query parameters.</jc>
+		RequestQuery query = req.getQuery();
+		<jk>int</jk> q1 = query.get(<js>"q1"</js>, 0, <jk>int</jk>.<jk>class</jk>);
+		String q2 = query.get(<js>"q2"</js>, String.<jk>class</jk>);
+		UUID q3 = query.get(<js>"q3"</js>, UUID.<jk>class</jk>);
+
+		<jc>// Path remainder after pattern match.</jc>
+		String remainder = req.getPathMatch().getRemainder();
+
+		<jc>// Headers.</jc>
+		String lang = req.getHeader(<js>"Accept-Language"</js>);
+		String accept = req.getHeader(<js>"Accept"</js>);
+		<jk>int</jk> doNotTrack = req.getHeaders().get(<js>"DNT"</js>,
<jk>int</jk>.<jk>class</jk>);
+
+		<jc>// Send back a simple String response</jc>
+		String output = String.format(
+				<js>"method=%s, p1=%s, p2=%d, p3=%s, remainder=%s, q1=%d, q2=%s, q3=%s, lang=%s,
accept=%s, dnt=%d"</js>,
+				method, p1, p2, p3, remainder, q1, q2, q3, lang, accept, doNotTrack);
+		res.setOutput(output);  <jc>// Or use getWriter().</jc>
+	}
+		</p>	
+		
+		<h5 class='topic'>Methodology #3 - Intermediate-level API objects</h5>	
+		<p>
+			This approach is sort of the middle ground where you get access functional area APIs.
+		</p>
+		<p class='bcode'>
+	<ja>@RestMethod</ja>(name=<jsf>GET</jsf>, path=<js>"/example3/{p1}/{p2}/{p3}/*"</js>)
+	<jk>public</jk> String example3(
+			HttpMethod method,           <jc>// HTTP method.</jc>
+			RequestPathMatch path,       <jc>// Path variables.</jc>
+			RequestQuery query,          <jc>// Query parameters.</jc>
+			RequestHeaders headers,      <jc>// Headers.</jc>
+			AcceptLanguage lang,         <jc>// Specific header classes.</jc>
+			Accept accept
+		) {
+		
+		<jc>// Path variables.</jc>
+		String p1 = path.get(<js>"p1"</js>, String.<jk>class</jk>);
+		<jk>int</jk> p2 = path.get(<js>"p2"</js>, <jk>int</jk>.<jk>class</jk>);
+		UUID p3 = path.get(<js>"p3"</js>, UUID.<jk>class</jk>);
+
+		<jc>// Query parameters.</jc>
+		<jk>int</jk> q1 = query.get(<js>"q1"</js>, 0, <jk>int</jk>.<jk>class</jk>);
+		String q2 = query.get(<js>"q2"</js>, String.<jk>class</jk>);
+		UUID q3 = query.get(<js>"q3"</js>, UUID.<jk>class</jk>);
+
+		<jc>// Path remainder after pattern match.</jc>
+		String remainder = path.getRemainder();
+
+		<jc>// Headers.</jc>
+		int doNotTrack = headers.get(<js>"DNT"</js>, <jk>int</jk>.<jk>class</jk>);
+
+		<jc>// Send back a simple String response</jc>
+		String output = String.format(
+				<js>"method=%s, p1=%s, p2=%d, p3=%s, remainder=%s, q1=%d, q2=%s, q3=%s, lang=%s,
accept=%s, dnt=%d"</js>,
+				method, p1, p2, p3, remainder, q1, q2, q3, lang, accept, doNotTrack);
+		res.setOutput(output);
+	}
+		</p>	
+		<p>
+			All three are completely equivalent.  It's up to your own coding preferences which methodology
you use.
+		</p>
+		<br><hr>
+		<p>
+			Lifecycle hooks allow you to hook into lifecycle events of the servlet or REST call.
+			Like <ja>@RestMethod</ja> methods, the list of parameters are specified by
the developer.
+		</p>
+		<p>
+			For example, if you want to add an initialization method to your resource:
+		</p>
+		<p class='bcode'>
+	<ja>@RestResource</ja>(...)
+	<jk>public class</jk> MyResource  {
+
+		<jc>// Our database.</jc>
+		<jk>private</jk> Map&lt;Integer,Object&gt; <jf>myDatabase</jf>;
+
+		<ja>@RestHook</ja>(<jsf>INIT</jsf>)
+		<jk>public void</jk> initMyDatabase(RestConfig config) <jk>throws</jk>
Exception {
+			<jf>myDatabase</jf> = <jk>new</jk> LinkedHashMap&lt;&gt;();
+		}
+	}
+		</p>
+		<p>
+			Or if you want to intercept REST calls:
+		</p>
+		<p class='bcode'>
+	<ja>@RestResource</ja>(...)
+	<jk>public class</jk> MyResource {
+
+		<jc>// Add a request attribute to all incoming requests.</jc>
+		<ja>@RestHook</ja>(<jsf>PRE_CALL</jsf>)
+		<jk>public void</jk> onPreCall(RestRequest req) {
+			req.setAttribute(<js>"foo"</js>, <js>"bar"</js>);
+		}
+	}
+		</p>
+		<p>
+			The hook events can be broken down into two categories:
+		</p>
+		<ul class='spaced-list'>
+			<li>Resource lifecycle events:
+				<ul>
+					<li><jsf>INIT</jsf> - Right before initialization.
+					<li><jsf>POST_INIT</jsf> - Right after initialization.
+					<li><jsf>POST_INIT_CHILD_FIRST</jsf> - Right after initialization,
but run child methods first.
+					<li><jsf>DESTROY</jsf> - Right before servlet destroy.
+				</ul>
+			<li>REST call lifecycle events:
+				<ul>
+					<li><jsf>START_CALL</jsf> - At the beginning of a REST call.
+					<li><jsf>PRE_CALL</jsf> - Right before the <ja>@RestMethod</ja>
method is invoked.
+					<li><jsf>POST_CALL</jsf> - Right after the <ja>@RestMethod</ja>
method is invoked.
+					<li><jsf>END_CALL</jsf> - At the end of the REST call after the response
has been flushed.
+				</ul>
+		</ul>
+		<br><hr>
+		<p>
+			Auto-generated OPTIONS pages are constructed from Swagger DTO beans, here shown serialized
as HTML:
+		</p>
+		<img class='bordered' src='images/Swagger.png' width="800px">
+		<p>
+			Swagger documentation can be populated from annotations (as above), resource bundles,
or Swagger JSON files.
+		</p>
+		<p>
+			The page shown above is implemented on the RestServletDefault class in the method below
which shows that it's doing nothing more than 
+			serializing a Swagger bean which is constructed in the RestRequest object:
+		</p>
+		<p class='bcode'>
+	<ja>@RestMethod</ja>(name=<jsf>OPTIONS</jsf>, path=<js>"/*"</js>)
+	<jk>public</jk> Swagger getOptions(RestRequest req) {
+		<jk>return</jk> req.getSwagger();
+	}
+		</p>
+		<br><br><hr>
+		<p>	
+			Navigable hierarchies of REST resources are easy to set up either programmatically or
through annotations.
+			<br>
+			The following example is the <code>RootResources</code> class from the REST
examples showing how to construct
+			a grouping of resources using the <code>children()</code> annotation:
+		</p>
+		<p class='bcode'>
+	<ja>@RestResource</ja>(
+		path=<js>"/"</js>,
+		title=<js>"Root resources"</js>,
+		description=<js>"Example of a router resource page."</js>,
+		widgets={
+			PoweredByApache.<jk>class</jk>,
+			ContentTypeMenuItem.<jk>class</jk>
+		},
+		htmldoc=<ja>@HtmlDoc</ja>(
+			links={
+				<js>"options: ?method=OPTIONS"</js>,
+				<js>"$W{ContentTypeMenuItem}"</js>,
+				<js>"source: $C{Source/gitHub}/org/apache/juneau/examples/rest/RootResources.java"</js>
+			},
+			aside={
+				<js>"&lt;div style='max-width:400px' class='text'&gt;"</js>,
+				<js>"	&lt;p&gt;This is an example of a 'router' page that serves as a jumping-off
point to child resources.&lt;/p&gt;"</js>,
+				<js>"	&lt;p&gt;Resources can be nested arbitrarily deep through router
pages.&lt;/p&gt;"</js>,
+				<js>"	&lt;p&gt;Note the options link provided that lets you see the generated
swagger doc for this page.&lt;/p&gt;"</js>,
+				<js>"	&lt;p&gt;Also note the source link on these pages to view the source
code for the page.&lt;/p&gt;"</js>,
+				<js>"	&lt;p&gt;All content on pages in the UI are serialized POJOs.  In
this case, it's a serialized array of beans with 2 properties, 'name' and 'description'.&lt;/p&gt;"</js>,
+				<js>"	&lt;p&gt;Other features (such as this aside) are added through annotations.&lt;/p&gt;"</js>,
+				<js>"&lt;/div&gt;"</js>
+			},
+			footer=<js>"$W{PoweredByApache}"</js>
+		),
+		children={
+			HelloWorldResource.<jk>class</jk>,
+			PetStoreResource.<jk>class</jk>,
+			SystemPropertiesResource.<jk>class</jk>,
+			MethodExampleResource.<jk>class</jk>,
+			RequestEchoResource.<jk>class</jk>,
+			TempDirResource.<jk>class</jk>,
+			AddressBookResource.<jk>class</jk>,
+			SampleRemoteableServlet.<jk>class</jk>,
+			PhotosResource.<jk>class</jk>,
+			AtomFeedResource.<jk>class</jk>,
+			JsonSchemaResource.<jk>class</jk>,
+			SqlQueryResource.<jk>class</jk>,
+			TumblrParserResource.<jk>class</jk>,
+			CodeFormatterResource.<jk>class</jk>,
+			UrlEncodedFormResource.<jk>class</jk>,
+			ConfigResource.<jk>class</jk>,
+			LogsResource.<jk>class</jk>,
+			DockerRegistryResource.<jk>class</jk>,
+			ShutdownResource.<jk>class</jk>
+		}
+	)
+	<jk>public class</jk> RootResources <jk>extends</jk> RestServletGroupDefault
{ <jc>/* No code needed! */</jc> }
+		</p>
+		<p>
+			The above resource when rendered in HTML shows how easy it is to discover and navigate
to child resources using a browser:
+		</p>
+		<img class='bordered' src='images/Samples_RootResources.png' width="800px">
+		<p>
+			Resources can be nested arbitrarily deep.  
+			The <ja>@RestResource</ja> and <ja>@RestMethod</ja> annotations
can be applied to any classes, not just
+			servlets.  The only requirement is that the top-level resource be a subclass of <code>RestServlet</code>
as a hook into
+			the servlet container.
+		</p>
+		
+		<p>
+			The <code>juneau-examples-rest</code> project includes various other examples
that highlight some of the 
+			capabilities of the REST servlet API.
+			<br>
+			For example, the <code>PetStoreResource</code> class shows some advanced features
such as using POJO renders
+			and converters, and HTML widgets.
+		</p>
+		<img class='bordered' src='images/PetStore.png' width="1000px">
+		
+		<p>
+			The beans being serialized are shown here:
+		</p>
+		<p class='bcode'>
+	<jc>// Our bean class.</jc>
+	<jk>public class</jk> Pet {
+
+		<ja>@Html</ja>(link=<js>"servlet:/{id}"</js>)  <jc>// Creates
a hyperlink in HTML view.</jc>
+		<ja>@NameProperty</ja>                <jc>// Links the parent key to
this bean.</jc>
+		<jk>public int</jk> <jf>id</jf>;
+
+		<jk>public</jk> String <jf>name</jf>;
+		<jk>public</jk> Kind <jf>kind</jf>;
+
+		<ja>@BeanProperty</ja>(format=<js>"$%.2f"</js>)  <jc>// Renders
price in dollars.</jc>
+		<jk>public float</jk> <jf>price</jf>;
+
+		<ja>@BeanProperty</ja>(swap=DateSwap.<jsf>RFC2822D</jsf>.<jk>class</jk>)
 <jc>// Renders dates in RFC2822 format.</jc>
+		<jk>public</jk> Date <jf>birthDate</jf>;
+
+		<jk>public int</jk> getAge() {
+			Calendar c = <jk>new</jk> GregorianCalendar();
+			c.setTime(<jf>birthDate</jf>);
+			<jk>return new</jk> GregorianCalendar().get(Calendar.<jsf>YEAR</jsf>)
- c.get(Calendar.<jsf>YEAR</jsf>);
+		}
+	}
+
+	<ja>@Html</ja>(render=KindRender.<jk>class</jk>)  <jc>// Render
as an icon in HTML.</jc>
+	<jk>public static enum</jk> Kind {
+		<jsf>CAT</jsf>, <jsf>DOG</jsf>, <jsf>BIRD</jsf>, <jsf>FISH</jsf>,
<jsf>MOUSE</jsf>, <jsf>RABBIT</jsf>, <jsf>SNAKE</jsf>
+	}
+
+	<jk>public static class</jk> KindRender <jk>extends</jk> HtmlRender&lt;Kind&gt;
{
+		<ja>@Override</ja>
+		<jk>public</jk> Object getContent(SerializerSession session, Kind value) {
+			<jk>return new</jk> Img().src(<js>"servlet:/htdocs/"</js>+value.toString().toLowerCase()+<js>".png"</js>);
+		}
+		<ja>@Override</ja>
+		<jk>public</jk> String getStyle(SerializerSession session, Kind value) {
+			<jk>return</jk> <js>"background-color:#FDF2E9"</js>;
+		}
+	}
+		</p>
+	
+		<p>
+			The <code>QUERY</code> menu item shows the capabilities of Converters which
are post-processors that
+			work to filter POJOs after they've been returned by your Java method.
+			<br>
+			In this case, we're using the <code>Queryable</code> converter that allows
us to perform search/view/sort/paging
+			against collections of beans:
+		</p>
+		<img class='bordered' src='images/PetStore_Query.png' width="1000px">
+	
+		<p>
+			The drop-down menu items are implemented through "widgets" which allow you to embed arbitrary
HTML, Javascript, 
+			and CSS in the HTML view of the page.
+		</p>
+		<p class='bcode'>
+	<ja>@RestMethod</ja>(
+		name=<jsf>GET</jsf>,
+		path=<js>"/"</js>,
+		summary=<js>"The complete list of pets in the store"</js>,
+		
+		<jc>// Add 'query' and 'content-types' menu items.</jc>
+		widgets={
+			QueryMenuItem.<jk>class</jk>,
+			ContentTypeMenuItem.<jk>class</jk>,
+			StyleMenuItem.<jk>class</jk>
+		},
+
+		<jc>// Add our converter for POJO query support.</jc>
+		converters=Queryable.<jk>class</jk>,
+		
+		<jc>// Add our menu items in the nav links.</jc>
+		htmldoc=<ja>@HtmlDoc</ja>(
+			links={
+				<js>"up: request:/.."</js>,
+				<js>"options: servlet:/?method=OPTIONS"</js>,
+				<js>"$W{QueryMenuItem}"</js>,
+				<js>"$W{ContentTypeMenuItem}"</js>,
+				<js>"$W{StyleMenuItem}"</js>,
+				<js>"source: $C{Source/gitHub}/org/apache/juneau/examples/rest/PetStoreResource.java"</js>
+			}
+		)
+	)
+	<jk>public</jk> Collection&lt;Pet&gt; getPets() {
+		</p>
+		
+		<p>
+			HTML views are highly customizable with abilities such as defining your own look-and-feel
and even allowing
+			you to define your own templates.
+		</p>
+		<p>
+			For example, the PetStore page above rendered in one of the other predefined stylesheets:
+		</p>	
+		<img class='bordered' src='images/PetStore_light.png'>
+		<br><hr>
+		<p>
+			Automatic error handling is provided for a variety of conditions: 
+		</p>
+		<ul>
+			<li>Automatic 401 errors (Unauthorized) on failed guards.
+			<li>Automatic 404 errors (Not Found) on unmatched path patterns.
+			<li>Automatic 405 errors (Method Not Implemented) on unimplemented methods.
+			<li>Automatic 406 errors (Not Acceptable) when no matching serializer was found
to handle the <l>Accept</l> header.
+			<li>Automatic 412 errors (Precondition Failed) when all matchers failed to match.
+			<li>Automatic 415 errors (Unsupported Media Type) when no matching parser was found
was found to handle the <l>Content-Type</l> header.
+			<li>Automatic 500 errors on uncaught exceptions.
+			<li>Throw your own runtime RestException with HTTP status and response object. 
+		</ul>
+		<p>
+			Other features include: 
+		</p> 
+		<ul class='spaced-list'>
+			<li>Extremely simple debuggability using nothing more than your browser.
+			<li>Simplified localization support.
+			<li>Configurability through external INI files.
+			<li>Client-versioned responses (and other customizable heuristic matching APIs).
+			<li>Define and use your own HTML stylesheets.
+			<li>Lots of up-to-date documentation and examples.
+			<li>MUCH MORE!....
+		</ul>
+	
+		<ul class='doctree'>
+			<li class='link'>See <a class='doclink' href='http://juneau.incubator.apache.org/site/apidocs/overview-summary.html#juneau-rest-server'>juneau-rest-server</a>
for more information.
+		</ul>
+		
+		<h6 class='toc' id='juneau-rest-server.UIvsDI'>5.1.1 - User Interfaces (UI) vs. Developer
Interfaces (DI)</h6>
+		<div>
+			<p>
+				An important distinction needs to be made about the HTML representations produced by
the REST
+				API.  These should not be considered User Interfaces, but rather Developer Interfaces.
+			</p>
+			<p>
+				UIs should hide the end-user from the underlying architecture.
+				The audience generally consists of non-technical people not interested in how the UI
works.  
+			</p>
+			<p>
+				DIs, on the other hand, should NOT hide the end-user from the underlying architecture.
 
+				Instead, it's a thin veneer over the REST interface with the following goals:
+			</p>
+			<ul class='spaced-list'>
+				<li>Make it easy for the developer to explore and understand the REST API.
+				<li>Make it easy for the developer to debug the REST API using simple tools (hopefully
just a browser).
+			</ul>		
+			<p>
+				As a result, the following guidelines are recommended: 
+			</p>		
+			<ul class='spaced-list'>
+				<li>
+					Use titles/descriptions/asides to describe why the REST interface exists.
+					A developer knowing little about it should be able to access it with a browser and quickly

+					understand what it is and how to use it.
+				<li>
+					Don't hide the raw data!  
+					The HTML view should simply be considered an easier-to-read representation of the data
normally 
+					rendered in JSON or some other format.
+				<li>
+					Limit your use of Javascript!  
+					You can use it sparingly if you want to implement something simple like a pull-down
menu to 
+					simplify some debug task, but remember that your audience cares more about interacting
with your 
+					service programmatically using REST.  
+					Remember that the HTML is just icing on the cake.
+				<li>
+					Don't use it to implement a Web 2.0 interface!  
+					If you want a Web 2.0 UI, implement it separately ON TOP OF this REST interface.
+					The architecture is flexible enough that you could in theory pull in and use jQuery,
React, 
+					Angular, or any number of sophisticated Javascript UI frameworks.  Resist the urge to
do so.
+			</ul>		
+		</div>			
+	</div>
+
+	<!-- =======================================================================================================
-->
+	<!-- === JUNEAU-REST-SERVER-JAXRS ==========================================================================
-->
+	<!-- =======================================================================================================
-->
+
+	<h5 class='toc' id='juneau-rest-server-jaxrs'>juneau-rest-server-jaxrs</h5>
+	<div>
+		<h6 class='figure'>Maven Dependency</h6>
+		<p class='bcode' style='width:500px;'>
+	<xt>&lt;dependency&gt;</xt>
+		<xt>&lt;groupId&gt;</xt>org.apache.juneau<xt>&lt;/groupId&gt;</xt>
+		<xt>&lt;artifactId&gt;</xt>juneau-rest-server-jaxrs<xt>&lt;/artifactId&gt;</xt>
+		<xt>&lt;version&gt;</xt>6.4.0-incubating<xt>&lt;/version&gt;</xt>
+	<xt>&lt;/dependency&gt;</xt>
+		</p>	
+	
+		<h6 class='figure'>Java Library</h6>
+		<p class='bcode' style='width:500px;'>
+	juneau-rest-server-jaxrs-6.4.0-incubating.jar 
+		</p>	
+		
+		<h6 class='figure'>OSGi Module</h6>
+		<p class='bcode' style='width:500px;'>
+	org.apache.juneau.rest.server.jaxrs_6.4.0-incubating.jar 
+		</p>	
+		
+		<p>
+			The <code>juneau-rest-server-jaxrs</code> module defines predefined <code>MessageBodyReader</code>
and 
+			<code>MessageBodyWriter</code> implementations for using Juneau serializers
and parsers in JAX-RS environments.
+			It consists of the following classes:
+		</p>	
+		<ul class='spaced-list'>
+			<li>
+				<code>org.apache.juneau.rest.jaxrs.BaseProvider</code> - The base provider
class that implements the JAX-RS 
+				<code>MessageBodyReader</code> and <code>MessageBodyWriter</code>
interfaces.
+			<li>
+				<code>org.apache.juneau.rest.jaxrs.JuneauProvider</code> - Annotation that
is applied to subclasses of <code>BaseProvider</code>
+				to specify the serializers/parsers associated with a provider, and optionally filters
and properties to 
+				apply to those serializers and parsers.
+			<li>
+				<code>org.apache.juneau.rest.jaxrs.DefaultProvider</code> - A default provider
that provides the same level
+				of media type support as the <code>RestServletDefault</code> class.
+		</ul>
+		<p>
+			The JAX/RS support does provide you will the full marshalling capabilities of Juneau.
+			However, it should be noted that you lose some sophisticated functionality by not using
the REST servlet
+			API (such as the Developer Interfaces, guards, path matchers, localization, auto-generated
Swagger docs, etc...).
+		</p>
+
+		<ul class='doctree'>
+			<li class='link'>See <a class='doclink' href='http://juneau.incubator.apache.org/site/apidocs/overview-summary.html#juneau-rest-server-jaxrs'>juneau-rest-server-jaxrs</a>
for more information.
+		</ul>ß
+	</div>
+</body>
+</html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-juneau-website/blob/e87529b2/content/svl.html
----------------------------------------------------------------------
diff --git a/content/svl.html b/content/svl.html
new file mode 100644
index 0000000..1a5e714
--- /dev/null
+++ b/content/svl.html
@@ -0,0 +1,89 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+	@import url("styles/juneau-code.css");
+	@import url("styles/juneau-doc.css");
+</style>
+</head>
+<body>
+	<!-- =======================================================================================================
-->
+	<!-- === JUNEAU-SVL ========================================================================================
-->
+	<!-- =======================================================================================================
-->
+	
+	<h5 class='toc' id='juneau-svl'>juneau-svl</h5>
+	<div>
+		<h6 class='figure'>Maven Dependency</h6>
+		<p class='bcode' style='width:500px;'>
+	<xt>&lt;dependency&gt;</xt>
+		<xt>&lt;groupId&gt;</xt>org.apache.juneau<xt>&lt;/groupId&gt;</xt>
+		<xt>&lt;artifactId&gt;</xt>juneau-svl<xt>&lt;/artifactId&gt;</xt>
+		<xt>&lt;version&gt;</xt>6.4.0-incubating<xt>&lt;/version&gt;</xt>
+	<xt>&lt;/dependency&gt;</xt>
+		</p>	
+	
+		<h6 class='figure'>Java Library</h6>
+		<p class='bcode' style='width:500px;'>
+	juneau-svl-6.4.0-incubating.jar 
+		</p>	
+	
+		<h6 class='figure'>OSGi Module</h6>
+		<p class='bcode' style='width:500px;'>
+	org.apache.juneau.svl_6.4.0-incubating.jar 
+		</p>	
+	
+		<p>
+			The <code>juneau-svl</code> module defines an API for a language called "Simple
Variable Language".
+			In a nutshell, Simple Variable Language (or SVL) is text that contains variables of the
form
+			<js>"$varName{varKey}"</js>.
+		</p>
+		<p>
+			Variables can be recursively nested within the varKey (e.g. <js>"$FOO{$BAR{xxx},$BAZ{xxx}}"</js>).
+			Variables can also return values that themselves contain more variables.
+		</p>
+		<p class='bcode'>
+	<jc>// Use the default variable resolver to resolve a string that contains $S (system
property) variables</jc>
+	String myProperty = VarResolver.<jsf>DEFAULT</jsf>.resolve(<js>"The Java
home directory is $S{java.home}"</js>);
+		</p>
+		<p>
+			The following shows how variables can be arbitrarily nested...
+		</p>
+		<p class='bcode'>
+	<jc>// Look up a property in the following order:
+	// 1) MYPROPERTY environment variable.
+	// 2) 'my.property' system property if environment variable not found.
+	// 3) 'not found' string if system property not found.</jc>
+	String myproperty = VarResolver.<jsf>DEFAULT</jsf>.resolve(<js>"$E{MYPROPERTY,$S{my.property,not
found}}"</js>);
+	 	</p>
+		<p>
+			SVL is a large topic on it's own. 
+			It is used extensively in the ConfigFile, REST and Microservice APIs.
+		</p>
+		<p>
+			The following is the default list of supported variables:
+		</p>
+		<ul>
+			<li><code>$ARG{keyOrIndex[,defaultValue]}</code> - Command-line argument.
+			<li><code>$C{key[,defaultValue]}</code> - Config file entry.
+			<li><code>$E{envVar[,defaultValue]}</code> - Environment variable.
+			<li><code>$F{path[,defaultValue]}</code> - File resource.
+			<li><code>$I{name[,defaultValue]}</code> - Servlet init parameter.
+			<li><code>$L{key[,args...]}</code> - Localized message.
+			<li><code>$MF{key[,defaultValue]}</code> - Manifest file entry.
+			<li><code>$R{key[,args...]}</code> - Request variable.
+			<li><code>$S{systemProperty[,defaultValue]}</code> - System property.
+			<li><code>$SA{contentType,key[,defaultValue]}</code> - Serialized request
attribute.
+			<li><code>$U{uri}</code> - URI resolver.
+			<li><code>$UE{uriPart}</code> - URL-Encoder.
+			<li><code>$W{widgetName}</code> - HTML widget variable.
+		</ul>
+		<p>
+			Plugging in your own variables is also easy.
+		</p>
+		
+		<ul class='doctree'>
+			<li class='link'>See <a class='doclink' href='http://juneau.incubator.apache.org/site/apidocs/overview-summary.html#juneau-svl'>juneau-svl</a>
for more information.
+		</ul>
+	</div>
+</body>
+</html>
\ No newline at end of file


Mime
View raw message