SlideShare uma empresa Scribd logo
1 de 44
Baixar para ler offline
ERRest and Dojo
Pascal Robert
Overview
•   The basics

•   Security

•   Dojo and ERRest

    •   Using Dojo's DataGrid and JsonRestStore

    •   Client-side validation with JSON Schema

    •   Transactions

•   Todo
The basics
The basics

•   Think of REST as direct actions with specific action per HTTP
    methods (GET, POST, etc.).

•   ERRest will create/modify EOs based on data sent by the client,
    not need to call request().formValueForKey().

•   No envelope on the request, if meta-data is needed, it will use
    the HTTP headers or parameters in the URL.
HTTP methods and actions
             HTTP method                                   Action
                     GET                                 Read (fetch)
                    POST                                   Create
                     PUT                                   Update
                  DELETE                                   Delete
* This slide was taken from Mike's WOWODC 2009 session
One gotcha : you need to use the HTTP adaptor
from Wonder or WO 5.4 for DELETE and PUT
                   support.
Basic architecture of ERRest
•   ERRest uses the same architecture as the REST support in Ruby
    on Rails.

•   You build controllers for each entity you want to offer as REST
    services.

•   You create routes that you register in the REST request hander,
    and the routes are connected to controllers.

•   Check Mike's session from WOWODC West 2009 for more
    details on the architecture.
Routes and actions
     HTTP method                     URL                         Action

          GET                      /movies                   fetch all movies

          GET                    /movies/100             fetch movie with id 100

         POST                      /movies               create new movie object

          PUT                    /movies/100               update movie id 100

        DELETE                   /movies/100               delete movie id 100


* This slide was taken from Mike's WOWODC 2009 session
ERXDefaultRouteController


•   Provides abstract methods for all REST actions.

•   One line registration in the REST request handler
ERXRestFormat
•   Parse the request and write the response in different formats :
    •   JSON

    •   JS (same as JSON, but with a different MIME type)

    •   ASCII plist (iPhone/OS X apps!)

    •   XML

    •   SproutCore (JSON with specific properties)

    •   Rails (XML, but with a different format)

    •   Some chocolate and nuts framework that we can't talk about

•   Default format is XML
Filtering

•   You may not want to return all attributes and all relationships
    attributes in your response.

•   Filtering works with ERXKeyFilter.

•   You can have an different filter per route.
DEMO
Security
Security

•   You don't want anyone to be able to delete any objects...

•   The most popular way to do this is with "authkeys".

•   Ask users to send the key in the URL...

•   ... and use request().stringFormValueForKey to get it

•   Use HTTPS when using auth keys!
Security
    	   protected void checkAuthKey() throws SecurityException {
         String pw = context().request().stringFormValueForKey("pw");
         if(!("mySecretKey".equals(pw))) {
	   	   	 throw new SecurityException("Invalid authorization key");
         }
	   }

	   public WOActionResults indexAction() throws Throwable {
        checkAuthKey();
	   	 return response(editingContext(), MyEOClass.ENTITY_NAME, movies, showFilter()).generateResponse();
	   }
Same Origin Policy

•   XMLHttpRequest won't load (but will fetch) data if the
    XMLHttpRequest call is not in the same domain as the REST
    service, it's the Same Origin Policy.

•   4 options to get over that policy : window.name, HTTP Access
    Control, proxing or JSONP.
Same Origin Policy
•   HTTP Access Protocol sends a OPTIONS HTTP call to the
    service with specific headers.
    •   Access-Control-Request-Method

    •   Access-Control-Request-Headers

    •   Origin

•   REST service must reply to the OPTIONS request with some
    options

•   Supported by Safari 4+, Firefox 3.5+, IE 8 and Chrome 5
Same Origin Policy


To support HTTP Access Control, you have to add a route for the
OPTIONS method:
restReqHandler.insertRoute(new ERXRoute(Movie.ENTITY_NAME,"/movies",
ERXRoute.Method.Options,MoviesController.class, "options"));


Add the optionsAction method in your controller:
public WOActionResults optionsAction() throws Throwable {
  ERXResponse response = new ERXResponse();
  response.setHeader("*", "Access-Control-Allow-Origin");
  response.setHeaders(this.request().headersForKey("Access-Control-Request-Method"), "Access-
Control-Allow-Methods");
  response.setHeaders(this.request().headersForKey("Access-Control-Request-Headers"), "Access-
Control-Allow-Headers");
  response.setHeader("1728000", "Access-Control-Max-Age");
  return response;
}
Same Origin Policy


You also need to set the headers in the response of your other
actions :
public WOActionResults indexAction() throws Throwable {
...
	 WOResponse response = response(editingContext(), Movie.ENTITY_NAME, movies, showFilter
()).generateResponse();
	 response.setHeader("*", "Access-Control-Allow-Origin");
	 return response;
}
Same Origin Policy
•   window.name uses a iFrame to communicate with the REST
    service, and the XMLHTTPRequest fetch the data locally from
    the iFrame window.name property.

    •   Adds "windowname=true" to the query

    •   Response must be text/html wrapped in script tag

•   JSONP is the same concept, but use a <script> tag instead of an
    iFrame.

•   Good alternative for older browsers that don't support HTTP
    Access Control.
Same Origin Policy


Adding window.name support
public WOActionResults indexAction() throws Throwable {
...
	 String windowNameArg = this.request().stringFormValueForKey("windowname");
	 if ((windowNameArg != null) && ("true".equals(windowNameArg))) {
	 	 String content = response.contentString().replaceAll("n", "");
	 	 response.setContent("<html><script type="text/javascript">window.name='" + content +
"';</script></html>");
	 	 response.setHeader("text/html", "Content-Type");
	 }
	 return response;
}
Same Origin Policy


•   Last option : proxing on the client side, where the client
    XMLHTTPRequest makes its request to a local service (WO, JSP,
    PHP, etc.) and that service connects to your service.
DOJO
DOJO

•   First release in March 2005

•   Managed by the Dojo Foundation, backed by IBM, Sun and others

•   Dual licensed : BSD and Academic Free

•   Latest release is 1.5, on July 15th 2010
DOJO

•   Lots of data widgets (Grid, Tree, etc.) and stores (JSON, Flickr,
    Picasa, etc.).

•   Create a store that use the dojo.data system and it will be
    available for all data widgets like the DataGrid.

•   Switching to a different store might require only one line of
    change.
JsonRestStore
•   Easy to use data store.
    dojo.require("dojox.data.JsonRestStore");

    var jsonStore = new dojox.data.JsonRestStore({ target: "/ra/movies" });


•   store.save() method will contact your REST service to save
    changes.

•   Must change the default format in your REST controller to
    JSON.
    protected ERXRestFormat defaultFormat() { return ERXRestFormat.JSON; }
DataGrid

•   DataGrid displays data from a data store in a table.

•   Columns are resizable and sortable.

•   Paging is supported.

•   Rows are editable.
DataGrid paging
•   In the data grid properties, add :

    rowsPerPage="a int value"


•   Dojo will send an extra header when paging is required :

    Range: 0-19


•   The REST service must reply with :

    Content-Range: 0-19/99
Adding new objects


•   We can add new objects to the store, they will be created
    server-side when the save() method is called on the store.

•   The new object have to be added to the store with the newItem
    () method.
JSON Schema
•   Define the structure of JSON data.

•   List of properties for the JSON object. Type can be string,
    number, integer, object, array, enum, etc.

•   You can reference other schemas, including schemas specified at
    full URLs.

•   Dojo can use it to perform client side validation.

•   We can call it WSDL for JSON, with less chat.
JSON Schema example
     {
    "name":"Movie",
    "properties":{
        "title":{
            "maxLength":255,
            "minLength":1,
            "type":"string"
        },
        "dateReleased":{
            "optional":true,
            "format":"date-time",
            "type":"string"
        },
        "category":{
            "maxLength":20,
            "optional":true,
            "type":"string"
        }
     }
}
JSON Schema


•   Wait... We already have the list of properties in the model...

•   ... So we should generate the schema from the controller...
Schema generation
      	   public WOActionResults indexAction() throws Throwable {
...
	     	   String schemaArg = this.request().stringFormValueForKey("schema");
	     	   if (schemaArg != null) {
	     	   	   return schemaAction(showFilter());
	     	   }
	     }

	     public WOActionResults schemaAction(ERXKeyFilter keyFilter) {
	     	   HashMap rootObject = new HashMap();
	     	   rootObject.put("name", Movie.ENTITY_NAME);
	     	   HashMap properties = new HashMap();
	     	
	     	   addSchemaProperties(properties, Movie.ENTITY_NAME, keyFilter);
	     	
	     	   rootObject.put("properties", properties);
	     	
	     	   WOResponse response = new WOResponse();
	     	   response.setHeader("application/json", "Content-Type");
	     	   response.setContent(JSONSerializer.toJSON(rootObject, ERXJSONRestWriter._config).toString());
	     	   return response;
	     }
Schema generation
      	   protected void addSchemaProperties(HashMap properties, String entityName, ERXKeyFilter keyFilter) {
	     	   EOEntity entity = EOModelGroup.globalModelGroup().entityNamed(entityName);
	     	   EOClassDescription classDescription = ERXRestClassDescriptionFactory.classDescriptionForEntityName(entityName);

	     	   for   (String attributeName : (NSArray<String>) classDescription.attributeKeys()) {
	     	   	     ERXKey<Object> key = new ERXKey<Object>(attributeName);
	     	   	     if (keyFilter.matches(key, ERXKey.Type.Attribute)) {
	     	   	     	   EOAttribute attribute = entity.attributeNamed(key.key());
	     	   	     	   if (attribute != null) {
	     	   	     	   	   HashMap property = new HashMap();
	     	   	     	   	   if (attribute.allowsNull()) {
	     	   	     	   	   	   property.put("optional", true);
	     	   	     	   	   }
	     	   	     	   	   if (attribute.className().equals("java.lang.String")) {
	     	   	     	   	   	   property.put("type", "string");
	     	   	     	   	   	   if (attribute.width() > 0) {
	     	   	     	   	   	   	   property.put("maxLength",attribute.width());
	     	   	     	   	   	   	   if ((property.get("optional") == null) || (!(Boolean)property.get("optional"))) {
	     	   	     	   	   	   	   	   property.put("minLength",1);
	     	   	     	   	   	   	   }
	     	   	     	   	   	   }
	     	   	     	   	   }
...
	     	   	     	   	   properties.put(attribute.name(), property);
	     	   	     	   }
	     	   	     }
	     	   }
	     }
Schema generation
    <script type="text/javascript">
	   var theSchema;

	   function fetchSchema() {
	   	   var xhrArgs = {
	           url: "/cgi-bin/WebObjects/Movies.woa/-6100/ra/movies?schema=true",
	   	   	   handleAs: "json",
	   	       sync: true,
	   	   	   load: function(data){
	   	            theSchema = data;
	   	   	   },
	   	   	   error: function(error){
	   	   	        console.log = "An unexpected error occurred: " + error;
	   	   	   }
	       }		    	
	   	   dojo.xhrGet(xhrArgs);	 	   	
	   }

	   fetchSchema();

    var jsonStore = new dojox.data.JsonRestStore({
        target: "/cgi-bin/WebObjects/Movies.woa/-6100/ra/movies",
        schema: theSchema
    });
</script>
JSON Schema


•   With JSON schema, when adding new items to the store,
    validation will be done client-side, no need to contact the server
    for basic validation.
Transactions
•   When store.save() is called, if multiple objects have to be saved,
    Dojo will add a Transaction, a Seq-Id and a Client-Seq-Id headers.

•   The value of the header is either Open or Commit.

•   Seq-Id is a integer with the transaction number.

•   Client-Seq-Id is a unique id per browser page.

•   Only one problem : transactions are not sent in order!

•   Let see this in action!
DEMO
Todo


•   JSON Referencing

•   HTML5 Storage

•   Service Mapping Description (SMD)
JSON Referencing
•   Instead of putting the content of related objects in the root
    object, you put references to those objects.

•   Dojo will do lazy-loading of the related objects, eg it will fetch
    them when needed.

•   Data will look like this :
    {
        "title": "title",
        "studio": {"$ref": "/studio/1" }
    }


•   http://www.sitepen.com/blog/2008/11/21/effective-use-of-jsonreststore-referencing-lazy-loading-
    and-more/
HTML5 Storage

•   Dojo 1.5 have support for HTML5 local storage, but I didn't find
    the documention for it.

•   Previous Dojo versions have OfflineRest, but it uses Flash (doh!)
    as the data storage engine for WebKit browsers, and Google
    Gears on Firefox.
Service Mapping Description
•   SMD describes available services, just like WSDL for SOAP.

•   JSON Schema is part of SMD.

•   Look like this:
    {
        target:"/jsonrpc",
        transport:"POST",
        envelope:"JSON-RPC-1.2",
        SMDVersion:"2.0",
        services: {
            add : { // define a service to add two numbers
            parameters: [
                {name:"a",type:"number"}, // define the two parameters
                {name:"b",type:"number"}
            ],
            returns:{"type":"number"}
        }
    }


•   http://www.sitepen.com/blog/2008/03/19/pluggable-web-services-with-smd/
Resources

•   http://dojotoolkit.org/

•   http://docs.dojocampus.org/dojox/data/JsonRestStore

•   http://docs.dojocampus.org/dojox/grid/DataGrid

•   http://www.sitepen.com/blog/2008/10/31/json-schema/

•   http://www.sitepen.com/blog/2008/07/22/windowname-transport/
Q&A

Mais conteúdo relacionado

Mais procurados

Morphia: Simplifying Persistence for Java and MongoDB
Morphia:  Simplifying Persistence for Java and MongoDBMorphia:  Simplifying Persistence for Java and MongoDB
Morphia: Simplifying Persistence for Java and MongoDB
Jeff Yemin
 
Active Record Query Interface (1), Season 2
Active Record Query Interface (1), Season 2Active Record Query Interface (1), Season 2
Active Record Query Interface (1), Season 2
RORLAB
 

Mais procurados (20)

Morphia: Simplifying Persistence for Java and MongoDB
Morphia:  Simplifying Persistence for Java and MongoDBMorphia:  Simplifying Persistence for Java and MongoDB
Morphia: Simplifying Persistence for Java and MongoDB
 
«Objective-C Runtime в примерах» — Алексей Сторожев, e-Legion
«Objective-C Runtime в примерах» — Алексей Сторожев, e-Legion«Objective-C Runtime в примерах» — Алексей Сторожев, e-Legion
«Objective-C Runtime в примерах» — Алексей Сторожев, e-Legion
 
Simplifying Persistence for Java and MongoDB with Morphia
Simplifying Persistence for Java and MongoDB with MorphiaSimplifying Persistence for Java and MongoDB with Morphia
Simplifying Persistence for Java and MongoDB with Morphia
 
Apache Solr 1.4 – Faster, Easier, and More Versatile than Ever
Apache Solr 1.4 – Faster, Easier, and More Versatile than EverApache Solr 1.4 – Faster, Easier, and More Versatile than Ever
Apache Solr 1.4 – Faster, Easier, and More Versatile than Ever
 
Http4s, Doobie and Circe: The Functional Web Stack
Http4s, Doobie and Circe: The Functional Web StackHttp4s, Doobie and Circe: The Functional Web Stack
Http4s, Doobie and Circe: The Functional Web Stack
 
How and Where in GLORP
How and Where in GLORPHow and Where in GLORP
How and Where in GLORP
 
Getting the most out of Java [Nordic Coding-2010]
Getting the most out of Java [Nordic Coding-2010]Getting the most out of Java [Nordic Coding-2010]
Getting the most out of Java [Nordic Coding-2010]
 
Solr 6 Feature Preview
Solr 6 Feature PreviewSolr 6 Feature Preview
Solr 6 Feature Preview
 
Hibernate
Hibernate Hibernate
Hibernate
 
Developing application for Windows Phone 7 in TDD
Developing application for Windows Phone 7 in TDDDeveloping application for Windows Phone 7 in TDD
Developing application for Windows Phone 7 in TDD
 
Apache Solr + ajax solr
Apache Solr + ajax solrApache Solr + ajax solr
Apache Solr + ajax solr
 
JDBC - JPA - Spring Data
JDBC - JPA - Spring DataJDBC - JPA - Spring Data
JDBC - JPA - Spring Data
 
Object Oriented Exploitation: New techniques in Windows mitigation bypass
Object Oriented Exploitation: New techniques in Windows mitigation bypassObject Oriented Exploitation: New techniques in Windows mitigation bypass
Object Oriented Exploitation: New techniques in Windows mitigation bypass
 
Squeak DBX
Squeak DBXSqueak DBX
Squeak DBX
 
Active Record Query Interface (1), Season 2
Active Record Query Interface (1), Season 2Active Record Query Interface (1), Season 2
Active Record Query Interface (1), Season 2
 
XQuery Design Patterns
XQuery Design PatternsXQuery Design Patterns
XQuery Design Patterns
 
Requery overview
Requery overviewRequery overview
Requery overview
 
greenDAO
greenDAOgreenDAO
greenDAO
 
Spring data requery
Spring data requerySpring data requery
Spring data requery
 
Rapid Prototyping with Solr
Rapid Prototyping with SolrRapid Prototyping with Solr
Rapid Prototyping with Solr
 

Semelhante a ERRest and Dojo

Data Access Options in SharePoint 2010
Data Access Options in SharePoint 2010Data Access Options in SharePoint 2010
Data Access Options in SharePoint 2010
Rob Windsor
 
Ajaxtechnicalworkshopshortversion 1224845432835700-8
Ajaxtechnicalworkshopshortversion 1224845432835700-8Ajaxtechnicalworkshopshortversion 1224845432835700-8
Ajaxtechnicalworkshopshortversion 1224845432835700-8
anuradha raheja
 
Ajax tutorial
Ajax tutorialAjax tutorial
Ajax tutorial
Kat Roque
 
Consuming RESTful services in PHP
Consuming RESTful services in PHPConsuming RESTful services in PHP
Consuming RESTful services in PHP
Zoran Jeremic
 
WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...
Fabio Franzini
 

Semelhante a ERRest and Dojo (20)

ERRest - The Next Steps
ERRest - The Next StepsERRest - The Next Steps
ERRest - The Next Steps
 
Data Access Options in SharePoint 2010
Data Access Options in SharePoint 2010Data Access Options in SharePoint 2010
Data Access Options in SharePoint 2010
 
Life outside WO
Life outside WOLife outside WO
Life outside WO
 
Ajaxtechnicalworkshopshortversion 1224845432835700-8
Ajaxtechnicalworkshopshortversion 1224845432835700-8Ajaxtechnicalworkshopshortversion 1224845432835700-8
Ajaxtechnicalworkshopshortversion 1224845432835700-8
 
Ajax tutorial
Ajax tutorialAjax tutorial
Ajax tutorial
 
Painless Persistence in a Disconnected World
Painless Persistence in a Disconnected WorldPainless Persistence in a Disconnected World
Painless Persistence in a Disconnected World
 
Everybody Loves AFNetworking ... and So Can you!
Everybody Loves AFNetworking ... and So Can you!Everybody Loves AFNetworking ... and So Can you!
Everybody Loves AFNetworking ... and So Can you!
 
Consuming RESTful Web services in PHP
Consuming RESTful Web services in PHPConsuming RESTful Web services in PHP
Consuming RESTful Web services in PHP
 
Consuming RESTful services in PHP
Consuming RESTful services in PHPConsuming RESTful services in PHP
Consuming RESTful services in PHP
 
Introduction to node.js
Introduction to node.jsIntroduction to node.js
Introduction to node.js
 
Intro to Sail.js
Intro to Sail.jsIntro to Sail.js
Intro to Sail.js
 
Local data storage for mobile apps
Local data storage for mobile appsLocal data storage for mobile apps
Local data storage for mobile apps
 
Node.js: The What, The How and The When
Node.js: The What, The How and The WhenNode.js: The What, The How and The When
Node.js: The What, The How and The When
 
Introduction to ajax
Introduction to ajaxIntroduction to ajax
Introduction to ajax
 
JSLT: JSON querying and transformation
JSLT: JSON querying and transformationJSLT: JSON querying and transformation
JSLT: JSON querying and transformation
 
WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...
 
SwampDragon presentation: The Copenhagen Django Meetup Group
SwampDragon presentation: The Copenhagen Django Meetup GroupSwampDragon presentation: The Copenhagen Django Meetup Group
SwampDragon presentation: The Copenhagen Django Meetup Group
 
Ajax xml json
Ajax xml jsonAjax xml json
Ajax xml json
 
AJAX.pptx
AJAX.pptxAJAX.pptx
AJAX.pptx
 
ITT 2014 - Erik Hellmann - Android Programming - Smarter and Better Networking
ITT 2014 - Erik Hellmann - Android Programming - Smarter and Better NetworkingITT 2014 - Erik Hellmann - Android Programming - Smarter and Better Networking
ITT 2014 - Erik Hellmann - Android Programming - Smarter and Better Networking
 

Mais de WO Community

Mais de WO Community (20)

KAAccessControl
KAAccessControlKAAccessControl
KAAccessControl
 
In memory OLAP engine
In memory OLAP engineIn memory OLAP engine
In memory OLAP engine
 
Using Nagios to monitor your WO systems
Using Nagios to monitor your WO systemsUsing Nagios to monitor your WO systems
Using Nagios to monitor your WO systems
 
Build and deployment
Build and deploymentBuild and deployment
Build and deployment
 
High availability
High availabilityHigh availability
High availability
 
Reenabling SOAP using ERJaxWS
Reenabling SOAP using ERJaxWSReenabling SOAP using ERJaxWS
Reenabling SOAP using ERJaxWS
 
Chaining the Beast - Testing Wonder Applications in the Real World
Chaining the Beast - Testing Wonder Applications in the Real WorldChaining the Beast - Testing Wonder Applications in the Real World
Chaining the Beast - Testing Wonder Applications in the Real World
 
D2W Stateful Controllers
D2W Stateful ControllersD2W Stateful Controllers
D2W Stateful Controllers
 
Deploying WO on Windows
Deploying WO on WindowsDeploying WO on Windows
Deploying WO on Windows
 
Unit Testing with WOUnit
Unit Testing with WOUnitUnit Testing with WOUnit
Unit Testing with WOUnit
 
Apache Cayenne for WO Devs
Apache Cayenne for WO DevsApache Cayenne for WO Devs
Apache Cayenne for WO Devs
 
Advanced Apache Cayenne
Advanced Apache CayenneAdvanced Apache Cayenne
Advanced Apache Cayenne
 
Migrating existing Projects to Wonder
Migrating existing Projects to WonderMigrating existing Projects to Wonder
Migrating existing Projects to Wonder
 
iOS for ERREST - alternative version
iOS for ERREST - alternative versioniOS for ERREST - alternative version
iOS for ERREST - alternative version
 
iOS for ERREST
iOS for ERRESTiOS for ERREST
iOS for ERREST
 
"Framework Principal" pattern
"Framework Principal" pattern"Framework Principal" pattern
"Framework Principal" pattern
 
Filtering data with D2W
Filtering data with D2W Filtering data with D2W
Filtering data with D2W
 
WOver
WOverWOver
WOver
 
Localizing your apps for multibyte languages
Localizing your apps for multibyte languagesLocalizing your apps for multibyte languages
Localizing your apps for multibyte languages
 
WOdka
WOdkaWOdka
WOdka
 

Último

Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
panagenda
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Victor Rentea
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
?#DUbAI#??##{{(☎️+971_581248768%)**%*]'#abortion pills for sale in dubai@
 

Último (20)

Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
WSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering Developers
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot ModelMcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
Platformless Horizons for Digital Adaptability
Platformless Horizons for Digital AdaptabilityPlatformless Horizons for Digital Adaptability
Platformless Horizons for Digital Adaptability
 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
 
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
 

ERRest and Dojo

  • 2. Overview • The basics • Security • Dojo and ERRest • Using Dojo's DataGrid and JsonRestStore • Client-side validation with JSON Schema • Transactions • Todo
  • 4. The basics • Think of REST as direct actions with specific action per HTTP methods (GET, POST, etc.). • ERRest will create/modify EOs based on data sent by the client, not need to call request().formValueForKey(). • No envelope on the request, if meta-data is needed, it will use the HTTP headers or parameters in the URL.
  • 5. HTTP methods and actions HTTP method Action GET Read (fetch) POST Create PUT Update DELETE Delete * This slide was taken from Mike's WOWODC 2009 session
  • 6. One gotcha : you need to use the HTTP adaptor from Wonder or WO 5.4 for DELETE and PUT support.
  • 7. Basic architecture of ERRest • ERRest uses the same architecture as the REST support in Ruby on Rails. • You build controllers for each entity you want to offer as REST services. • You create routes that you register in the REST request hander, and the routes are connected to controllers. • Check Mike's session from WOWODC West 2009 for more details on the architecture.
  • 8. Routes and actions HTTP method URL Action GET /movies fetch all movies GET /movies/100 fetch movie with id 100 POST /movies create new movie object PUT /movies/100 update movie id 100 DELETE /movies/100 delete movie id 100 * This slide was taken from Mike's WOWODC 2009 session
  • 9. ERXDefaultRouteController • Provides abstract methods for all REST actions. • One line registration in the REST request handler
  • 10. ERXRestFormat • Parse the request and write the response in different formats : • JSON • JS (same as JSON, but with a different MIME type) • ASCII plist (iPhone/OS X apps!) • XML • SproutCore (JSON with specific properties) • Rails (XML, but with a different format) • Some chocolate and nuts framework that we can't talk about • Default format is XML
  • 11. Filtering • You may not want to return all attributes and all relationships attributes in your response. • Filtering works with ERXKeyFilter. • You can have an different filter per route.
  • 12. DEMO
  • 14. Security • You don't want anyone to be able to delete any objects... • The most popular way to do this is with "authkeys". • Ask users to send the key in the URL... • ... and use request().stringFormValueForKey to get it • Use HTTPS when using auth keys!
  • 15. Security protected void checkAuthKey() throws SecurityException { String pw = context().request().stringFormValueForKey("pw"); if(!("mySecretKey".equals(pw))) { throw new SecurityException("Invalid authorization key"); } } public WOActionResults indexAction() throws Throwable { checkAuthKey(); return response(editingContext(), MyEOClass.ENTITY_NAME, movies, showFilter()).generateResponse(); }
  • 16. Same Origin Policy • XMLHttpRequest won't load (but will fetch) data if the XMLHttpRequest call is not in the same domain as the REST service, it's the Same Origin Policy. • 4 options to get over that policy : window.name, HTTP Access Control, proxing or JSONP.
  • 17. Same Origin Policy • HTTP Access Protocol sends a OPTIONS HTTP call to the service with specific headers. • Access-Control-Request-Method • Access-Control-Request-Headers • Origin • REST service must reply to the OPTIONS request with some options • Supported by Safari 4+, Firefox 3.5+, IE 8 and Chrome 5
  • 18. Same Origin Policy To support HTTP Access Control, you have to add a route for the OPTIONS method: restReqHandler.insertRoute(new ERXRoute(Movie.ENTITY_NAME,"/movies", ERXRoute.Method.Options,MoviesController.class, "options")); Add the optionsAction method in your controller: public WOActionResults optionsAction() throws Throwable { ERXResponse response = new ERXResponse(); response.setHeader("*", "Access-Control-Allow-Origin"); response.setHeaders(this.request().headersForKey("Access-Control-Request-Method"), "Access- Control-Allow-Methods"); response.setHeaders(this.request().headersForKey("Access-Control-Request-Headers"), "Access- Control-Allow-Headers"); response.setHeader("1728000", "Access-Control-Max-Age"); return response; }
  • 19. Same Origin Policy You also need to set the headers in the response of your other actions : public WOActionResults indexAction() throws Throwable { ... WOResponse response = response(editingContext(), Movie.ENTITY_NAME, movies, showFilter ()).generateResponse(); response.setHeader("*", "Access-Control-Allow-Origin"); return response; }
  • 20. Same Origin Policy • window.name uses a iFrame to communicate with the REST service, and the XMLHTTPRequest fetch the data locally from the iFrame window.name property. • Adds "windowname=true" to the query • Response must be text/html wrapped in script tag • JSONP is the same concept, but use a <script> tag instead of an iFrame. • Good alternative for older browsers that don't support HTTP Access Control.
  • 21. Same Origin Policy Adding window.name support public WOActionResults indexAction() throws Throwable { ... String windowNameArg = this.request().stringFormValueForKey("windowname"); if ((windowNameArg != null) && ("true".equals(windowNameArg))) { String content = response.contentString().replaceAll("n", ""); response.setContent("<html><script type="text/javascript">window.name='" + content + "';</script></html>"); response.setHeader("text/html", "Content-Type"); } return response; }
  • 22. Same Origin Policy • Last option : proxing on the client side, where the client XMLHTTPRequest makes its request to a local service (WO, JSP, PHP, etc.) and that service connects to your service.
  • 23. DOJO
  • 24. DOJO • First release in March 2005 • Managed by the Dojo Foundation, backed by IBM, Sun and others • Dual licensed : BSD and Academic Free • Latest release is 1.5, on July 15th 2010
  • 25. DOJO • Lots of data widgets (Grid, Tree, etc.) and stores (JSON, Flickr, Picasa, etc.). • Create a store that use the dojo.data system and it will be available for all data widgets like the DataGrid. • Switching to a different store might require only one line of change.
  • 26. JsonRestStore • Easy to use data store. dojo.require("dojox.data.JsonRestStore"); var jsonStore = new dojox.data.JsonRestStore({ target: "/ra/movies" }); • store.save() method will contact your REST service to save changes. • Must change the default format in your REST controller to JSON. protected ERXRestFormat defaultFormat() { return ERXRestFormat.JSON; }
  • 27. DataGrid • DataGrid displays data from a data store in a table. • Columns are resizable and sortable. • Paging is supported. • Rows are editable.
  • 28. DataGrid paging • In the data grid properties, add : rowsPerPage="a int value" • Dojo will send an extra header when paging is required : Range: 0-19 • The REST service must reply with : Content-Range: 0-19/99
  • 29. Adding new objects • We can add new objects to the store, they will be created server-side when the save() method is called on the store. • The new object have to be added to the store with the newItem () method.
  • 30. JSON Schema • Define the structure of JSON data. • List of properties for the JSON object. Type can be string, number, integer, object, array, enum, etc. • You can reference other schemas, including schemas specified at full URLs. • Dojo can use it to perform client side validation. • We can call it WSDL for JSON, with less chat.
  • 31. JSON Schema example { "name":"Movie", "properties":{ "title":{ "maxLength":255, "minLength":1, "type":"string" }, "dateReleased":{ "optional":true, "format":"date-time", "type":"string" }, "category":{ "maxLength":20, "optional":true, "type":"string" } } }
  • 32. JSON Schema • Wait... We already have the list of properties in the model... • ... So we should generate the schema from the controller...
  • 33. Schema generation public WOActionResults indexAction() throws Throwable { ... String schemaArg = this.request().stringFormValueForKey("schema"); if (schemaArg != null) { return schemaAction(showFilter()); } } public WOActionResults schemaAction(ERXKeyFilter keyFilter) { HashMap rootObject = new HashMap(); rootObject.put("name", Movie.ENTITY_NAME); HashMap properties = new HashMap(); addSchemaProperties(properties, Movie.ENTITY_NAME, keyFilter); rootObject.put("properties", properties); WOResponse response = new WOResponse(); response.setHeader("application/json", "Content-Type"); response.setContent(JSONSerializer.toJSON(rootObject, ERXJSONRestWriter._config).toString()); return response; }
  • 34. Schema generation protected void addSchemaProperties(HashMap properties, String entityName, ERXKeyFilter keyFilter) { EOEntity entity = EOModelGroup.globalModelGroup().entityNamed(entityName); EOClassDescription classDescription = ERXRestClassDescriptionFactory.classDescriptionForEntityName(entityName); for (String attributeName : (NSArray<String>) classDescription.attributeKeys()) { ERXKey<Object> key = new ERXKey<Object>(attributeName); if (keyFilter.matches(key, ERXKey.Type.Attribute)) { EOAttribute attribute = entity.attributeNamed(key.key()); if (attribute != null) { HashMap property = new HashMap(); if (attribute.allowsNull()) { property.put("optional", true); } if (attribute.className().equals("java.lang.String")) { property.put("type", "string"); if (attribute.width() > 0) { property.put("maxLength",attribute.width()); if ((property.get("optional") == null) || (!(Boolean)property.get("optional"))) { property.put("minLength",1); } } } ... properties.put(attribute.name(), property); } } } }
  • 35. Schema generation <script type="text/javascript"> var theSchema; function fetchSchema() { var xhrArgs = { url: "/cgi-bin/WebObjects/Movies.woa/-6100/ra/movies?schema=true", handleAs: "json", sync: true, load: function(data){ theSchema = data; }, error: function(error){ console.log = "An unexpected error occurred: " + error; } } dojo.xhrGet(xhrArgs); } fetchSchema(); var jsonStore = new dojox.data.JsonRestStore({ target: "/cgi-bin/WebObjects/Movies.woa/-6100/ra/movies", schema: theSchema }); </script>
  • 36. JSON Schema • With JSON schema, when adding new items to the store, validation will be done client-side, no need to contact the server for basic validation.
  • 37. Transactions • When store.save() is called, if multiple objects have to be saved, Dojo will add a Transaction, a Seq-Id and a Client-Seq-Id headers. • The value of the header is either Open or Commit. • Seq-Id is a integer with the transaction number. • Client-Seq-Id is a unique id per browser page. • Only one problem : transactions are not sent in order! • Let see this in action!
  • 38. DEMO
  • 39. Todo • JSON Referencing • HTML5 Storage • Service Mapping Description (SMD)
  • 40. JSON Referencing • Instead of putting the content of related objects in the root object, you put references to those objects. • Dojo will do lazy-loading of the related objects, eg it will fetch them when needed. • Data will look like this : { "title": "title", "studio": {"$ref": "/studio/1" } } • http://www.sitepen.com/blog/2008/11/21/effective-use-of-jsonreststore-referencing-lazy-loading- and-more/
  • 41. HTML5 Storage • Dojo 1.5 have support for HTML5 local storage, but I didn't find the documention for it. • Previous Dojo versions have OfflineRest, but it uses Flash (doh!) as the data storage engine for WebKit browsers, and Google Gears on Firefox.
  • 42. Service Mapping Description • SMD describes available services, just like WSDL for SOAP. • JSON Schema is part of SMD. • Look like this: { target:"/jsonrpc", transport:"POST", envelope:"JSON-RPC-1.2", SMDVersion:"2.0", services: { add : { // define a service to add two numbers parameters: [ {name:"a",type:"number"}, // define the two parameters {name:"b",type:"number"} ], returns:{"type":"number"} } } • http://www.sitepen.com/blog/2008/03/19/pluggable-web-services-with-smd/
  • 43. Resources • http://dojotoolkit.org/ • http://docs.dojocampus.org/dojox/data/JsonRestStore • http://docs.dojocampus.org/dojox/grid/DataGrid • http://www.sitepen.com/blog/2008/10/31/json-schema/ • http://www.sitepen.com/blog/2008/07/22/windowname-transport/
  • 44. Q&A