users@jersey.java.net

[Jersey] Re: stateless REST

From: Trenton D. Adams <trenton.d.adams_at_gmail.com>
Date: Fri, 10 Jun 2016 22:57:17 -0600

The records are very complicated. Over 1200 tables for just the one part
of the ERP.

On Fri, Jun 10, 2016 at 6:57 PM, Martynas Jusevičius <martynas_at_graphity.org>
wrote:

> What do your records look like?
>
> I think a wizard use case is solvable with hidden inputs. You submit the
> form of the initial step (probably as POST) to the second step, which then
> renders the first form as hidden inputs, and the second as visible. You
> submit to the third step, and so on and so on, until the final step where
> you can commit to persistent store.
>
> In other words, HTML forms keeps state :) It gets passed from one resource
> to the next one, and gets filtered/augmented/transformed in the process.
>
> On Sat, 11 Jun 2016 at 02:46, Trenton D. Adams <trenton.d.adams_at_gmail.com>
> wrote:
>
>> Hi Martynas,
>>
>> Thanks for the response. We have an ERP, which we cannot commit any
>> records to, until the final step. There's no intermediate steps, as we do
>> not want incomplete data in the database. It affects all sorts of other
>> parts of the ERP. So, if I should not maintain state, and cannot commit
>> records on the fly, how can I do processing per request only? The object
>> layer needs to maintain that state in some way, or I need to..
>>
>> 1. Store every bit of data in HTML5 session storage until the final step,
>> at which point I pass it all to the server to be committed.
>> 2. Commit every piece of data to the ERP as I go, so that statefulness in
>> the object layer is not needed. But, given we cannot do this with our ERP,
>> we'll need to develop a bunch of temporary tables to store the data, until
>> the final insert/update/commit.
>>
>> Are there other options?
>>
>> I've been reading "RESTful Java with JAX-RS 2.0" by Bill Burke. And the
>> examples he gives are entirely stateless. His book was written in a
>> perfect world where everything can and should be committed as you go,
>> thereby not needing any state, other than authentication. But it would be
>> extremely rare that such a utopian model would appear in the real world,
>> when dealing with large enterprise ERPs. So, it seems to me, that one must
>> resort to ENORMOUS amounts of work to adhere to a level of statelessness.
>> Things like creating temporary tables for data storage (re-inventing the
>> ERP wheeL), or some other mechanism such as HTML5 session storage. In both
>> cases, it seems to me that's a LOT of work. And it might be useful if
>> designing a system from the ground up; or maybe it's too much extra work
>> either way. That's essentially what I'm trying to determine here.
>>
>> On Fri, Jun 10, 2016 at 5:25 PM, Martynas Jusevičius <
>> martynas_at_graphity.org> wrote:
>>
>>> The component that keeps the state server-side it the persistent
>>> store. Besides that, it is not necessary to keep any state in the
>>> object layer which is client-specifing or spanning request. All
>>> processing should be done per-request, using request body and headers
>>> only. If it is a GET request, state is queried from the permanent
>>> store, otherwise state is change in it.
>>>
>>> HTTP and REST hypermedia define a uniform protocol, URIs are uniform
>>> identifiers. The last piece of a uniform hypermedia API: RDF, uniform
>>> data model. We've designed an approach that combines these
>>> technologies and enables a single, generic read-write web API:
>>>
>>> https://github.com/AtomGraph/Linked-Data-Templates/tree/master/XML%20London%202016%20paper
>>>
>>>
>>> Martynas
>>> atomgraph.com
>>>
>>> On Sat, Jun 11, 2016 at 12:13 AM, Trenton D. Adams
>>> <trenton.d.adams_at_gmail.com> wrote:
>>> > Hi Jason,
>>> >
>>> > Thanks for the response.
>>> >
>>> > So, you're using REST, but not maintaining state server side, yes?
>>> i.e. no
>>> > sessions. So, when you can't commit data to a database, until all of
>>> the
>>> > data is obtained, in your experience, how do you maintain that data
>>> until
>>> > the process is complete?
>>> >
>>> > Do you use HTML5 session storage?
>>> >
>>> > Do you not use JAX-RS for user responses (e.g. Jersey templates)?
>>> >
>>> > I'm curious. Partly because it seems like a lot of work to not have
>>> the
>>> > server maintain state. When the server maintains state, I can set all
>>> > variables from page 1 to page n on the server side, and use only a
>>> reference
>>> > to that object, and continue doing so until I'm complete, and I commit.
>>> > This is what makes EJB look so good to me.
>>> >
>>> > On Fri, Jun 10, 2016 at 3:55 PM, Jason Lee <jason_at_steeplesoft.com>
>>> wrote:
>>> >>
>>> >> I don't think that's a true statement ("The use of REST precludes
>>> >> maintaining state server side"). Of course the server-side maintains
>>> state:
>>> >> it has to have SOMETHING to transfer to the client, right? :) What the
>>> >> server-side should NOT do, in a pure RESTful architecture, is store
>>> some
>>> >> sort of client-specific state such as we might be used to used to
>>> doing with
>>> >> session-scoped beans in, say, a JSF application. In other words, it
>>> >> shouldn't have the notion of a client's *session* (including things
>>> like a
>>> >> client's current step in a wizard), but it certainly needs *state*
>>> ("no
>>> >> client context being stored on the server between requests").
>>> >>
>>> >> To address the "where to put the application logic" question from
>>> earlier
>>> >> in the thread, the server can (and should! :) react when the state
>>> changes
>>> >> in certain ways to perform system-specific processing. For example,
>>> the
>>> >> client updates the state of an Order entity to, say, SUBMITTED, the
>>> server
>>> >> notices this change (through means that aren't relevant here), and
>>> begins
>>> >> some sort of processing in the background.
>>> >>
>>> >> Moving all of the app's logic to the client is probably not a wise
>>> move
>>> >> for a number of reasons, though there will almost certainly be SOME
>>> logic
>>> >> there, such as validation, page flow coordination, etc.
>>> >>
>>> >> Having said all of that, we've tended to be pretty pragmatic on the
>>> >> systems I've worked on, adhering as strictly as possible to Fielding's
>>> >> notions, but deviating, grudgingly, when it made sense to do so
>>> (i.e., a
>>> >> strictly RESTful implementation would make the APIs usage slow,
>>> chatty,
>>> >> cumbersome, etc). For example, for authentication, one system had an
>>> >> endpoint to authenticate a user that would return an auth token (it
>>> might
>>> >> actually have been called a session ID :) that subsequent calls would
>>> then
>>> >> send in lieu of credentials. This was done, in part, so that if the
>>> token
>>> >> were intercepted and used, all that would be exposed to an attacker
>>> is that
>>> >> session and not the user's credentials (SSL helps, of course).
>>> >>
>>> >> Oh, and if I'm ever asked to implement HATEOAS again, I'll be tempted
>>> to
>>> >> rage quit. That was a terrible experience. :)
>>> >>
>>> >> At any rate, history (and personal experience ;) shows you CAN build
>>> >> complex applications with JAX-RS, but you do have to change how you
>>> think
>>> >> about designing the system.
>>> >>
>>> >>
>>> >> On 6/10/16 2:38 PM, Trenton D. Adams wrote:
>>> >>
>>> >> Your descriptions of what REST is what I would like it to be, but it
>>> isn't
>>> >> that, accrording to most everything I've read on it. If you're
>>> storing
>>> >> state, you're not using REST. The use of REST precludes maintaing
>>> state
>>> >> server side. I'm tempted to use JAX-RS regardless, and just not use
>>> the
>>> >> statelessness part.
>>> >>
>>> >>
>>> https://en.wikipedia.org/wiki/Representational_state_transfer#Stateless
>>> >> Stateless
>>> >> See also: Stateless protocol
>>> >> The client–server communication is further constrained by no client
>>> >> context being stored on the server between requests. Each request
>>> from any
>>> >> client contains all the information necessary to service the request,
>>> and
>>> >> session state is held in the client. The session state can be
>>> transferred by
>>> >> the server to another service such as a database to maintain a
>>> persistent
>>> >> state for a period and allow authentication. The client begins sending
>>> >> requests when it is ready to make the transition to a new state.
>>> While one
>>> >> or more requests are outstanding, the client is considered to be in
>>> >> transition. The representation of each application state contains
>>> links that
>>> >> may be used the next time the client chooses to initiate a new
>>> >> state-transition.[12]
>>> >>
>>> >>
>>> >> On Fri, Jun 10, 2016 at 1:04 PM, Robert Gacki
>>> >> <robert.gacki_at_contenttrace.org> wrote:
>>> >>>
>>> >>> Hi Trenton,
>>> >>>
>>> >>> I think, you misunderstand what REST is. REST is about how a server
>>> and
>>> >>> a client interacts to transfer state. The transport itself is
>>> stateless
>>> >>> ("dumb pipes"). It is an architectural style. The notion of state is
>>> >>> something the client and server have to implement themself. What REST
>>> >>> describes is nothing else what HTTP specifies, but is not limited to
>>> >>> HTTP (think of mail). In fact, Roy Fielding just took HTTP as an
>>> >>> example for REST in his dissertation.
>>> >>>
>>> >>> OSI Layer
>>> >>> ----------------------------------------------------
>>> >>> | Your server and/or client application | L |
>>> >>> ---------------------------------------------- a |
>>> >>> | REST as architectural style | y 7 |
>>> >>> ---------------------------------------------- e |
>>> >>> | HTTP|MAIL|<other req / res based protocols>| r |
>>> >>> ----------------------------------------------------
>>> >>> Layer 6 and below
>>> >>>
>>> >>> JAX RS is only about modelling REST principles and Jersey provides
>>> the
>>> >>> implementation. That does not include state management. So you should
>>> >>> see JAX RS as the protocol toolset ("dumb pipes") to build
>>> >>> applications. What you call stateful is application state and that is
>>> >>> always application / implementation specific. For example, the notion
>>> >>> of a session is purely application specific.
>>> >>>
>>> >>> So Jersey, at its core, does not provide you with components to build
>>> >>> things like a wizard. But it provides you the ability to build or use
>>> >>> existing components, like JSR 371 and its implementations.
>>> >>>
>>> >>> To your wizard example: You can solve wizards with different methods.
>>> >>> You described one solution, where the server does not store results
>>> of
>>> >>> previous wizard steps. Each solution has advantages and
>>> disadvantages.
>>> >>> But all solutions have something in common: they are application
>>> >>> specific. If you use HTTP as a communication protocol, you can use
>>> REST
>>> >>> principles to have a well-defined architectural style. But you still
>>> >>> need to figure out how to maintain state between a request and
>>> >>> response.
>>> >>>
>>> >>> An important part of REST is Hypermedia. For HTTP, this is just
>>> >>> payload. For an application built by REST principles, it is the state
>>> >>> that is transfered. And that state should include all information
>>> >>> necessary for server or client to support continous interactions. If
>>> >>> you use your browser and surf around, clicking on links or signing in
>>> >>> into your Google account, you are doing exactly what REST proposes
>>> for
>>> >>> all other media types - not just HTML.
>>> >>>
>>> >>> So your wizard solution is based on HTML (a representation) and is
>>> >>> constraint by the HTML specification and how browsers behave. Thus,
>>> you
>>> >>> may lose form field values when you use the browser's back button.
>>> But
>>> >>> you can do three things to counter that without storing state server-
>>> >>> side (outside request-response bounds): 1) You can provide a back
>>> >>> button inside the form that just submits to the server - the server
>>> >>> renders the previous page with the values from the hidden fields. 2)
>>> In
>>> >>> modern browsers, with Javascript enabled, you can store the state
>>> >>> client side and restore it when the user goes back. 3) SPAs mostly
>>> >>> avoid the problem by avoiding round-trips to the server, with the
>>> >>> disadvantage of cloning lots of server-side logic for the client
>>> >>> (validation, business logic).
>>> >>>
>>> >>> Robert
>>> >>>
>>> >>>
>>> >>> Am Freitag, den 10.06.2016, 12:11 -0600 schrieb Trenton D. Adams:
>>> >>> > Thanks for the responses guys. I'm thinking more along the lines
>>> of
>>> >>> > JAX-RS implementations, such as Jersey, providing a template based
>>> >>> > approach, where the result can be served by JSP. Technically,
>>> that's
>>> >>> > almost useless when doing it statelessly, unless your service is
>>> >>> > intended to return HTML to a client program, or you intend to
>>> violate
>>> >>> > the statelessness of REST. Cause like you say, writing BBAs, is
>>> >>> > actually quite tough without some nice statefulness.
>>> >>> >
>>> >>> > JSR 371 will be coming out too. Are they still expecting
>>> stateless?
>>> >>> > Cause it suddenly becomes less useful. Maintaining all the state
>>> in
>>> >>> > the browser's store is a lot of extra work, and just a plain weird
>>> >>> > way of dealing with it.
>>> >>> >
>>> >>> > On Fri, Jun 10, 2016 at 10:07 AM, <lenny_at_flowlogix.com> wrote:
>>> >>> > > Trenton, I feel your pain.
>>> >>> > > In all honesty, the technology architecture didn’t change all
>>> that
>>> >>> > > much in the last 10 years.
>>> >>> > > Don’t get caught up in the Rest/Microservices hype too much.
>>> >>> > > For BBAs (boring business apps) which I believe that you are
>>> >>> > > dealing with (and I also like developing),
>>> >>> > > it makes very little sense migrating to Rest-based architecture.
>>> >>> > > Concentrate on cleaning, refactoring, modularizing your code,
>>> using
>>> >>> > > the latest iterations of Java EE specs that you are already
>>> using.
>>> >>> > >
>>> >>> > > So, why all the hype?
>>> >>> > > Current Rest “state-of-the-art” today is actually in it’s very
>>> >>> > > infancy. It makes sense for some applications to do it though,
>>> but
>>> >>> > > not for BBAs.
>>> >>> > > What apps does the Stateless Rest APIs make sense for?
>>> >>> > > - Multiple clients written separately by different teams (i.e.
>>> >>> > > native iOS, native Android, native JavaScript)
>>> >>> > > - APIs that other companies use in different (non-Java) languages
>>> >>> > > - There are some other use cases also, but the above are the
>>> major
>>> >>> > > ones
>>> >>> > >
>>> >>> > > What’s the negative impact of Rest services today, as it relates
>>> to
>>> >>> > > Java client and server development?
>>> >>> > > - Massive violation of DRY principle, as it’s really meant for
>>> >>> > > client and server to be written in different languages,
>>> >>> > > i.e. client in JavaScript/iOS/Android and server in Java
>>> >>> > > - Data models are duplicated both in Java (on the server) and on
>>> >>> > > the client (JS/iOS/Android)
>>> >>> > > - Validation is duplicated on the client and server
>>> >>> > > - Some business logic may need to be duplicated in the client and
>>> >>> > > server
>>> >>> > >
>>> >>> > > The above negatives are something that are not solved by the
>>> >>> > > industry quite yet, and for BBAs, (IMHO) is not worth the effort.
>>> >>> > >
>>> >>> > > As far as answering your specific question, in “pure” Rest API,
>>> All
>>> >>> > > state is indeed handled by the client, including authentication.
>>> >>> > > Authentication is usually handled by “bearer token” paradigm, is
>>> >>> > > sent with every request to the server, and thus re-authenticated
>>> by
>>> >>> > > the server every time.
>>> >>> > > Yes, it sounds (and is) a bit less efficient on per-request basis
>>> >>> > > (throughput per instance), but does (horizontally) scale better
>>> to
>>> >>> > > millions of users.
>>> >>> > >
>>> >>> > >
>>> >>> > > > On Jun 9, 2016, at 4:40 PM, Trenton D. Adams
>>> <trenton.d.adams_at_gma
>>> >>> > > > il.com> wrote:
>>> >>> > > >
>>> >>> > > > One thing I didn't mention, is that I'm considering updating
>>> one
>>> >>> > > > of our enterprise apps to more modern technologies, where it
>>> >>> > > > actually saves effort. It is currently based on RMI, with a
>>> >>> > > > custom web front-end/mvc framework based on a the command
>>> >>> > > > pattern. So, I'm trying to determine whether we should do EJB
>>> or
>>> >>> > > > JAX-RS for the back-end, and possibly JAX-RS for the front end.
>>> >>> > > > One of the issues is that EJB is almost a drop in replacement
>>> for
>>> >>> > > > RMI. It would require significant more effort to switch to
>>> JAX-
>>> >>> > > > RS.
>>> >>> > > >
>>> >>> > > > When the back end is stateless, it's simply pushing the
>>> >>> > > > complexity to the client. It is now the client that must do
>>> all
>>> >>> > > > the work to know what it needs to send; i.e. it keeps it's own
>>> >>> > > > state. For the back end, that's HIGHLY scale-able technology
>>> >>> > > > wise, but has other drawbacks. With a stateful back-end, you
>>> >>> > > > just set the firstname, lastname, birthdate, etc, and pass
>>> around
>>> >>> > > > a reference to the back-end object, such as with EJB. Neither
>>> >>> > > > the front end nor the back end have to maintain much state,
>>> >>> > > > programmatically speaking; it's the service that does that (EJB
>>> >>> > > > for example). This saves developer time, does it not?
>>> >>> > > >
>>> >>> > > > It seems that using the html5 stuff would be a pain in the
>>> butt.
>>> >>> > > > Mainly because html5's storage system can't store a javascript
>>> >>> > > > object even, so you can't even abstract your data storage.
>>> Plus,
>>> >>> > > > we'd end up not supporting people with older machines/browsers.
>>> >>> > > > And then, if you have a series of web pages that a person is
>>> >>> > > > going through, you'd have to write code to grab all of that,
>>> and
>>> >>> > > > pass it to the server.
>>> >>> > > >
>>> >>> > > > So, should I not use JAX-RS if I'm wanting to maintain state?
>>> I
>>> >>> > > > mean it kind of goes against the "ST" in REST. Nothing
>>> actually
>>> >>> > > > prevents you from maintaining state though.
>>> >>> > > >
>>> >>> > > > I've read some articles where people say you shouldn't even be
>>> >>> > > > maintaining state of authentication. That I don't agree with,
>>> >>> > > > because some services don't even have access to the user's
>>> >>> > > > credentials. So at some point, someone is going to have to
>>> >>> > > > maintain state. So, you could either not use JAX-RS, or use it
>>> >>> > > > and maintain state while doing so, but essentially violate it's
>>> >>> > > > principles.
>>> >>> > > >
>>> >>> > > > Also, doesn't statelessness become very complex when you have
>>> >>> > > > larger enterprise applications?
>>> >>> > > >
>>> >>> > > > I see a lot of benefits of JAX-RS, and a lot of drawbacks. Am
>>> I
>>> >>> > > > missing something?
>>> >>> > > >
>>> >>> > > > On Wed, Jun 8, 2016 at 5:46 PM, cowwoc <
>>> cowwoc_at_bbs.darktech.org>
>>> >>> > > > wrote:
>>> >>> > > > > Define "application logic".
>>> >>> > > > >
>>> >>> > > > > In the case you mentioned below (storing the user's last name
>>> >>> > > > > somewhere) I would favor using localStorage and sessionStore
>>> to
>>> >>> > > > > store this information:
>>> http://www.w3schools.com/html/html5_web
>>> >>> > > > > storage.asp
>>> >>> > > > > The client would read the information from the local store
>>> and
>>> >>> > > > > use it to make AJAX calls.
>>> >>> > > > >
>>> >>> > > > > I misspoke earlier when I talked about Cookies. These are
>>> >>> > > > > typically used to reference to a server-side state that is
>>> >>> > > > > present across all calls. If some REST calls need one piece
>>> of
>>> >>> > > > > information and others need another, I would pull them from
>>> the
>>> >>> > > > > local/sessionStore and pass them to the AJAX calls as needed.
>>> >>> > > > >
>>> >>> > > > > Gili
>>> >>> > > > >
>>> >>> > > > >
>>> >>> > > > > On 2016-06-08 7:40 PM, Trenton D. Adams wrote:
>>> >>> > > > > > So are you saying push all the application logic to the
>>> >>> > > > > > browser, using javascript? Are cookies really intended to
>>> >>> > > > > > store a whole bunch of user data?
>>> >>> > > > > >
>>> >>> > > > > > I know with HTML5, you can use
>>> >>> > > > > > sessionStorage.setItem("lastname", "last name"). But, I
>>> >>> > > > > > don't think moving most application logic into a browser is
>>> >>> > > > > > very maintainable, maybe I'm wrong though.
>>> >>> > > > > >
>>> >>> > > > > > On Wed, Jun 8, 2016 at 5:29 PM, cowwoc
>>> <cowwoc_at_bbs.darktech.o
>>> >>> > > > > > rg> wrote:
>>> >>> > > > > > > Without commenting on the specifics of Jersey, I agree:
>>> >>> > > > > > > REST is for computers, not humans.
>>> >>> > > > > > >
>>> >>> > > > > > > I typically expose REST APIs for computers and use
>>> cookies
>>> >>> > > > > > > to maintain browser sessions. The browser can then read
>>> >>> > > > > > > stateful information from the Cookie and serve it to
>>> >>> > > > > > > stateless REST APIs. Not all clients are web-browsers, so
>>> >>> > > > > > > your REST API should be designed around non-browsers.
>>> >>> > > > > > >
>>> >>> > > > > > > Gili
>>> >>> > > > > > >
>>> >>> > > > > > >
>>> >>> > > > > > > On 2016-06-08 5:58 PM, Trenton D. Adams wrote:
>>> >>> > > > > > > > Good day,
>>> >>> > > > > > > >
>>> >>> > > > > > > > I'm a bit confused. I actually have two separate
>>> >>> > > > > > > > questions. I understand that REST is supposed to be
>>> done
>>> >>> > > > > > > > in a stateless way. For regular web services that's
>>> >>> > > > > > > > easy. I mean it really shifts a lot of the work to the
>>> >>> > > > > > > > client, where it seems to be more difficult to deal
>>> with,
>>> >>> > > > > > > > but as far as the server goes, it's simple.
>>> >>> > > > > > > >
>>> >>> > > > > > > > However, how is it even possible to use jersey
>>> templates
>>> >>> > > > > > > > without state (sessions), in a reasonable way? The
>>> >>> > > > > > > > browser isn't going to maintain the state. It seems
>>> that
>>> >>> > > > > > > > one would need to make sure each and every page puts
>>> >>> > > > > > > > hidden inputs from the previous form, in the html
>>> output,
>>> >>> > > > > > > > so that it is re-submitted with the new request. That
>>> >>> > > > > > > > would be a lot of work. If the user presses the back
>>> >>> > > > > > > > button, all that state vanishes, and the user must re-
>>> >>> > > > > > > > enter any screens they go forward to again. This
>>> doesn't
>>> >>> > > > > > > > make for a very good user experience.
>>> >>> > > > > > > >
>>> >>> > > > > > > > Can someone explain to me how the use of JAX-RS as an
>>> MVC
>>> >>> > > > > > > > framework is even possible in a reasonable way, while
>>> >>> > > > > > > > being stateless?
>>> >>> > > > > > > >
>>> >>> > > > > > > > Then, can someone explain to me how statelessness in a
>>> >>> > > > > > > > back-end REST web service, promotes good code design,
>>> >>> > > > > > > > where user interaction is a necessity? It seems to me
>>> >>> > > > > > > > that the client would then need to maintain all the
>>> >>> > > > > > > > state, thereby tightly coupling all the data points
>>> >>> > > > > > > > between the different controllers on the client.
>>> >>> > > > > > > > Something like EJB allows you to pass around the
>>> stateful
>>> >>> > > > > > > > pointer, and you simply add data as you go.
>>> >>> > > > > > > >
>>> >>> > > > > > > > After reading this stack exchange post, it's sounding
>>> >>> > > > > > > > like everyone thinks that REST is NOT for users, but
>>> for
>>> >>> > > > > > > > services only.
>>> >>> > > > > > > >
>>> http://stackoverflow.com/questions/3105296/if-rest-applic
>>> >>> > > > > > > > ations-are-supposed-to-be-stateless-how-do-you-manage-
>>> >>> > > > > > > > sessions
>>> >>> > > > > > > >
>>> >>> > > > > > > > I understand that it's more scalable, as the server
>>> >>> > > > > > > > always knows exactly what you want, because you're
>>> >>> > > > > > > > telling it every time. But it seems like that would
>>> come
>>> >>> > > > > > > > with a lot more boilerplate coding.
>>> >>> > > > > > > >
>>> >>> > > > > > > > Thanks.
>>> >>> > > > > > > >
>>> >>> > > > > > >
>>> >>> > > > >
>>> >>> > >
>>> >>
>>> >>
>>> >>
>>> >> --
>>> >> Jason Lee
>>> >> http://cubtracker.com
>>> >> http://blogs.steeplesoft.com
>>> >> http://twitter.com/jasondlee
>>> >> http://blogs.steeplesoft.com/+
>>> >> http://blogs.steeplesoft.com/in
>>> >
>>> >
>>>
>>
>>