restful web service with jboss fuse

Post on 15-Feb-2017

1.603 Views

Category:

Software

15 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Building JSON RESTful Web ServicesUsing JBoss Fuse

ejlp12@gmail.com

About THis PresentationThis presentation will focus on:

● RESful Web Service● JSON Format - No detail about XML or other format message transformation● JAX-RS standard - No detail about JAX-WS● Apache CXF● JBoss Fuse 6.2

RESTful Web Service

RESTful Web Services - INTRODUCTIONRepresentational State Transfer(REST)

● a software architecture style that centers around the transmission of data over HTTP, using only the four basic HTTP verbs.

● everything is a resource

● The state/data of the resource can be retrieved, changed, deleted commonly using HTTP verbs (GET, POST, PUT, DELETE, etc.)

● resource identified by Uniform Resource Identifiers (URIs), for example /people/unyil

Resource RepresentationCommonly used:

● JSON

{ "ID": "1", "Name": "Unyil Kucing", "Email": "unyil.kucing@gmail.com", "Country": "Indonesia"}

● XML

<Person> <ID>1</ID><Name>Unyil Kucing</Name><Email>unyil.kucing@gmail.com</Email><Country>India</Country></Person>

Request - Response ExamplePOST http://hostname/Person/ HTTP/1.1Host: hostnameContent-Type: text/xml; charset=utf-8Content-Length: 123

<?xml version="1.0" encoding="utf-8"?><Person> <ID>1</ID> <Name>Unyil Kucing</Name> <Email>unyil.kucing@gmail.com</Email> <Country>Indonesia</Country></Person>

HTTP/1.1 200 OKServer: ejlp-web-engine 1.0Content-Length: 263Content-Type: application/json; charset=utf-8

{ "ID": "1", "Name": "Unyil Kucing", "Email": "unyil.kucing@gmail.com", "Country": "Indonesia"}

Commonly URI & HTTP Method Usage Resource GET PUT POST DELETE

Collection URI, such as

http://api.example.com/resources/

List the URIs and perhaps

other details of the

collection's members.

Replace the

entire collection

with another

collection.

Create a new entry in the

collection. The new entry's

URI is assigned

automatically and is usually

returned by the operation.[11]

Delete the

entire

collection.

Element URI, such as

http://api.example.com/resources/item17

Retrieve a representation

of the addressed member

of the collection,

expressed in an

appropriate Internet media

type.

Replace the

addressed

member of the

collection, or if it

does not exist,

create it.

Not generally used. Treat the

addressed member as a

collection in its own right

andcreate a new entry in it.[11]

Delete the

addressed

member of

the

collection.

HTTP MethodMethod Operation performed on server Quality

GET Read a resource. Does not have any effect on the original value of the resource

PUT Insert a new resource or update if the resource already exists.

Gives the same result no matter how many times you perform it

POST Insert a new resource. Also can be used to update an existing resource.

N/A

DELETE Delete a resource . Gives the same result no matter how many times you perform it

OPTIONS List the allowed operations on a resource.

Does not have any effect on the original value of the resource

HEAD Return only the response headers and no response body.

Does not have any effect on the original value of the resource

HTTP Response Code200 OK General success status code. This is the most common code. Used to indicate success.201 CREATEDSuccessful creation occurred (via either POST or PUT). Set the Location header to contain a link to the newly-created resource (on POST). Response body content may or may not be present.

204 NO CONTENTIndicates success but nothing is in the response body, often used for DELETE and PUT operations.

400 BAD REQUESTGeneral error for when fulfilling the request would cause an invalid state. Domain validation errors, missing data, etc. are some examples.

401 UNAUTHORIZEDError code response for missing or invalid authentication token.

403 FORBIDDENError code for when the user is not authorized to perform the operation or the resource is unavailable for some reason (e.g. time constraints, etc.).

404 NOT FOUNDUsed when the requested resource is not found, whether it doesn't exist or if there was a 401 or 403 that, for security reasons, the service wants to mask.

HTTP Response Code405 METHOD NOT ALLOWEDUsed to indicate that the requested URL exists, but the requested HTTP method is not applicable. For example, POST /users/12345 where the API doesn't support creation of resources this way (with a provided ID). The Allow HTTP header must be set when returning a 405 to indicate the HTTP methods that are supported. In the previous case, the header would look like "Allow: GET, PUT, DELETE"

409 CONFLICTWhenever a resource conflict would be caused by fulfilling the request. Duplicate entries, such as trying to create two customers with the same information, and deleting root objects when cascade-delete is not supported are a couple of examples.

500 INTERNAL SERVER ERRORNever return this intentionally. The general catch-all error when the server-side throws an exception. Use this only for errors that the consumer cannot address from their end.

JSON FORMAT

JSON over XML● Still readable by human● Simple ● JSON does not have many concepts found in XML such as namespaces,

attributes or entity references● Support interface definition? YES

○ WADL○ Swagger○ RAML○ API Blueprint

Swagger UI

Swagger Example{ "swagger": "2.0", "info": { [...] }, "schemes": ["https"], "consumes": ["application/json"], "produces": ["application/json"], "paths": { "/user": { "get": { "responses": { "200": { "description": "users retrieved", "schema": { "type": "array", "items": { "$ref": "#/definitions/User" } } } } } } },

"definitions": { "User": { "type": "object", "additionalProperties": false, "properties": { "uid": { "type": "string" }, "email": { "type": "string" }, "phone": { "type": "string" } }, "required": ["uid", "email", "phone"] } }}

JSON and RESTful WS in

JBoss Fuse

RESTful Web Service in JBoss Fuse● RESTful Web Service is supported in JBoss Fuse by Apache CXF component● CXF implement JAX-RS standard● CXF can be used as REST Client or Server

Apache CFXCXF provides:

● Java API for building Web Service using JAX-WS○ Generating WSDL from Java classes and generating Java classes from WSDL○ WS-* standards support e.g. WS-Addressing, WS-Policy, WS-ReliableMessaging and

WS-Security○ etc

● Java API for RESTful Web Services JAX-RS 2.0 (JSR-339), JAX-RS 1.1 (JSR-311)○ Generating WADL from services, generating Java Interface from WADL

● Can be embedded in standalone app, used in Java EE Server app or in OSGi engine (JBoss Fuse)

RESTful Web Services in JBoss FuseCan be developed WITH or WITHOUT Camel

● WITH Camel○ Good for RESTful-ized a non JAX-RS Java Class ○ URI defined in config file (blueprint.xml)○ Options:

■ Using CXFRS component (http://camel.apache.org/cxfrs.html)■ Using REST wrapper layers

● REST DSL (in camel-core)

● Rest component (in camel-core)

● WITHOUT Camel:○ Good for Atomic Service○ No Routing (Integration flow)○ Create a RESTful (JAX-RS) web service using CXF and expose it with the OSGi HTTP

Service.○ URI, HTTP method is defined in Java Class using Anotation○ Quickstart project: https://github.com/jboss-fuse/quickstarts/tree/5715944/rest

RESTful service in CamelWrapper Layer:

● REST DSL (in camel-core)

● Rest component (in camel-core)

rest("/say").get("/hello/{name}") .route() .transform() .simple("Hello ${header.name}");

from("rest:get:say:/hello/{name}") .transform() .simple("Hello ${header.name}");

RESTful service in Camel● Spark-Rest component (in camel-spark-rest)

● Restlet component (in camel-restlet)● Servlet component (in camel-servlet)

JAX-RS1. The root URI for the resources exposed

by the service2. Public constructor3. HTTP verbs

4. Sub-resource, URI for the sub-resource, as specified using the the @Path annotation, is customerservice/order/id

Install & Run FuseBefore building and running this quick start you need:

● Maven 3.0.4 or higher

● JDK 1.6 or 1.7

● JBoss Fuse 6.2.1

unzip ~/RH_JBOSS_INSTALLER/Fuse_6.2.1/jboss-fuse-full-6.2.1.redhat-084.zip -d /Servers/

sed -i.orig 's/#admin/admin/g' /Servers//jboss-fuse-6.2.1.redhat-084/etc/users.properties

/Servers/jboss-fuse-6.2.1.redhat-084/bin/start

tail -f /Servers/jboss-fuse-6.2.1.redhat-084/data/log/fuse.log

$FUSE_HOME=/Servers/jboss-fuse-6.2.1.redhat-084

1. Install Fuse 6.2.12. Uncomment line “#admin” (remove “#”) to

set a username and password3. Start Fuse4. See the log file

Open to Fuse Client

cd /Servers/jboss-fuse-6.2.1.redhat-084/

./client

Fuse Directory Structure

Folder quickstart:

Simple sample project

Import Quickstart Project● Open Eclipse (JBDS), Create new Workspace● File > Import, “Existing Maven Projects”, Next● Root Directory: “/Servers/jboss-fuse-6.2.1.redhat-084/quickstarts/”● Next, Finish

Eclipse/JBDS Setting● Help > Preferences● Type “Maven” in the search textbox● Select Errors/Warning, change “Plugin execution…” to “Ignore”

Eclipse/JBDS Setting● Help > Preferences● Type “Maven” in the search textbox● JBoss Maven Integration > “Configure Maven Repositories..”

Maven repo: https://repository.jboss.org/nexus/content/groups/ea/

Project Structure

Some POJOs(Business Objects)

RESTful Service

OSGi Configuration File

Maven Configuration File

For real project, better to separate Business Object and Service classes in different

Maven Project

Navigate to Package Explorer view, and expand “cfx-rest” project

JAX-RS Service ProviderUsing Java annotation to define URI of the

service and documentation

Defining HTTP method, URI, resource type, documentation, HTTP

response code

Imported Package

JAX-RS

SWAGGER

OSGI-INF/bluerprint/blueprint.xml

Define the Service Provider bean to be

able to used by other

Documentation: JAX-RS Endpoint: https://access.redhat.com/documentation/en-US/Red_Hat_JBoss_Fuse/6.2.1/html/Apache_CXF_Development_Guide/JAXRSEndpointConfig.html

http://cxf.apache.org/docs/jaxrs-services-configuration.html#JAXRSServicesConfiguration-Blueprint

Create a REST serveraddress: http://hostname:

port/cfx/crm

Create a REST serveraddress: http://hostname:

port/cfx/crm

blueprint.xmlXML Namespace for JAX-RS using CXF

Prefix Namespace

(default) http://www.osgi.org/xmlns/blueprint/v1.0.0

cxf http://cxf.apache.org/blueprint/core

jaxrs http://cxf.apache.org/blueprint/jaxrs

Install Projectosgi:install -s mvn:org.jboss.quickstarts.fuse/cxf-rest/6.2.1.redhat-084

OSGi Server InformationOSGi > Server

Standaloneserver

information

JBoss FUSE Management ConsoleAccess to http://localhost:8181/hawtio

$FUSE_HOME/etc/jetty.xml:

<Property name="jetty.port" default="8181"/>

$FUSE_HOME/etc/org.ops4j.pax.web.cfg:

org.osgi.service.http.port=8181

Install New Bundle (Application)OSGi > Bundles

Textbox for Maven library

MAVEN REPOSITORY DIRECTORY:

Files as a result of Maven build and install command:`mvn clean install`

Click this to deploy application (cxf-res-6.2.1.redhat-084.jar)

OSGi Bundle ListOSGi > Bundles - Click Table View button

New installed bundle

Bundle Detail Information and ActionsOSGi > Bundles - Click “JBoss Fuse Quickstart: rest”

Action Button: Stop, Start, Refresh,

Update, Delete

Bundle Information● Maven Repo location● Some info from Maven POM file● Start level: order number when

Fuse starting

OSGi ServiceAdditional info

CFX REST Service Example

● http://localhost:8181/cxf/crm?_wadl● http://localhost:8181/cxf/crm/customerservice?_wadl&_type=xml

CFX REST Service Example

OSGi FeaturesOSGi > Features Select package

to see available

features that not installed

YET

CXF’s JAX-RSAdditional Topics

CXF: Attaching a WADL document<jaxrs:server address="/rest" docLocation="wadl/bookStore.wadl"> <jaxrs:serviceBeans> <bean class="org.bar.generated.BookStore"/> </jaxrs:serviceBeans></jaxrs:server>

CXF: Schema validationTo enable schema validation on incoming messages:

<jaxrs:server address="/rest" docLocation="wadl/bookStore.wadl"> <jaxrs:serviceBeans> <bean class="org.bar.generated.BookStore"/> </jaxrs:serviceBeans> <jaxrs:schemaLocations> <jaxrs:schemaLocation>classpath:/schemas/person.xsd</jaxrs:schemaLocation> <jaxrs:schemaLocation>classpath:/xsd/</jaxrs:schemaLocation> </jaxrs:schemaLocations></jaxrs:server>

CXF: Specifying the data bindingTo enable schema validation on incoming messages

<jaxrs:server id="jaxbbook" address="/jaxb"> <jaxrs:serviceBeans> <ref bean="serviceBean" /> </jaxrs:serviceBeans> <jaxrs:dataBinding> <bean class="org.apache.cxf.jaxb.JAXBDataBinding"/> </jaxrs:dataBinding></jaxrs:server>

<jaxrs:dataBinding> <bean class="org.apache.cxf.aegis.databinding.AegisDatabinding"> <property name="aegisContext"> <bean class="org.apache.cxf.aegis.AegisContext"> <property name="writeXsiTypes" value="true"/> </bean> </property> </bean> </jaxrs:dataBinding>

CXF: Extension mappingsto map the .xml or .json suffix automatically

OR

<jaxrs:server id="customerService" address="/"> <jaxrs:serviceBeans> <bean class="org.apache.cxf.jaxrs.systests.CustomerService" /> </jaxrs:serviceBeans> <jaxrs:extensionMappings> <entry key="json" value="application/json"/> <entry key="xml" value="application/xml"/> </jaxrs:extensionMappings></jaxrs:server>

GET /resource.xml HTTP/1.1

GET /resource.json HTTP/1.1

CXF: RESTful services without annotationsWe can defining REST services with XML (Model schema)

<jaxrs:server id="customerService" address="/customers" modelRef="classpath:/org/example/schemas/customer-resources.xml" />

https://access.redhat.com/documentation/en-US/Red_Hat_JBoss_Fuse/6.2.1/html/Apache_CXF_Development_Guide/JAXRSEndpointConfig-Model.html

<model xmlns="http://cxf.apache.org/jaxrs"> <resource name="org.apache.cxf.systest.jaxrs.BookStoreNoAnnotations" path="bookstore" produces="application/json" consumes="application/json"> <operation name="getBook" verb="GET" path="/books/{id}" produces="application/xml"> <param name="id" type="PATH"/> </operation> <operation name="getBookChapter" path="/books/{id}/chapter"> <param name="id" type="PATH"/> </operation> <operation name="updateBook" verb="PUT"> <param name="book" type="REQUEST_BODY"/> </operation> </resource> <resource name="org.apache.cxf.systest.jaxrs.ChapterNoAnnotations"> <operation name="getItself" verb="GET"/> <operation name="updateChapter" verb="PUT" consumes="application/xml"> <param name="content" type="REQUEST_BODY"/> </operation> </resource></model>

CXF: Swagger

<jaxrs:server id="xx" address="/address" /> <jaxrs:features> <bean class="io.fabric8.cxf.endpoint.SwaggerFeature">

<property name="title" value="Fabric8:CXF:Quickstarts - Customer Service" /><property name="description" value="Sample REST-based Customer Service" /><property name="version" value="${project.version}" />

</bean> </jaxrs:features></jaxrs:server>

CXF: Swagger http://localhost/cxf/crm/api-docs

Testing REST

REST Sample Testingcurl -X POST -T src/test/resources/add_customer.xml -H "Content-Type: application/xml" http://localhost:8181/cxf/crm/customerservice/customers

curl http://localhost:8181/cxf/crm/customerservice/customers/123

curl -X PUT -T src/test/resources/update_customer.xml -H "Content-Type: application/xml" http://localhost:8181/cxf/crm/customerservice/customers

curl -v -H "Accept: application/json" http://localhost:8181/cxf/crm/customerservice/customers/123

curl http://localhost:8181/cxf/crm/customerservice/customers/123?_type=json

Thank You :-) .

top related