So far, our REST service did not interact much with the existing Seaside todo application (other than through the shared model). Often it is however desired to have both — the application and the REST services — served from the same URL.
To achieve this we have to subclass
WARestfulFilter instead of
WARestfulFilter simply wraps a Seaside application. That is, it handles REST requests exactly as the
WARestfulHandler, but it can also delegate to the wrapped Seaside application.
To update our existing service we rename
ToDoFilter and change its superclass to
WARestfulFilter. Now the class definition should look like:
WARestfulFilter subclass: #ToDoFilter
A filter cannot be registered as a an independent entry point anymore, thus we should remove it from the dispatcher to avoid errors:
WAAdmin unregister: 'todo-api'
Instead we attach the filter the todo application itself. On the class-side of
ToDoListView we adapt the
initialize method to:
(WAAdmin register: self asApplicationAt: 'todo')
addFilter: ToDoFilter new
After evaluating the initialization code, the
ToDoFilter is now executed whenever somebody accesses our application. The process is visualized in Figure 157. Whenever a request hits the filter (1), it processes the annotations (2). Eventually, if none of the annotated methods matched, it delegates to the wrapped application by invoking the method noRouteFound: (3).
Unfortunately — if you followed the creation of the REST API in the previous sections — our
#list service hides the application by consuming all requests to http://localhost:8080/todo. We have two possibilities to fix the problem:
- We remove the method
noRouteFound:that eventually calls the application.
- We add a new service that captures requests directed at our web application and explicitly dispatches them to the Seaside application. For example, the following code triggers the wrapped application whenever HTML is requested:
^ self noRouteFound: self requestContext
This change leaves the existing API intact and lets users access our web application with their favorite web browser. This works, because browser request documents with the mime-type
text/html by default. Of course, we can combine this technique with any other of the matching techniques we discussed in the previous chapters.