SeasideSt / Seaside

The framework for developing sophisticated web applications in Smalltalk.
MIT License
514 stars 71 forks source link

REST depends on source code which is not available at deployment time in VASt and VW #852

Open adriaon opened 9 years ago

adriaon commented 9 years ago

Seaside REST depends on the availability of the source code. Sourcode however, is not available during deployment in VASt (and VW).

The Seaside REST framework needs the names of the arguments to the handler methods (see WARouteBuilder>>createComplexRoute). The only place this information exists is in the source code of the handler methods (see CompiledMethod>>greaseArgumentNames).

marschall commented 8 years ago

That's not quite true. The argument names are only needed if you want to map by argument name. It you map by argument index then the name is not required. This should also work if there's not source code available.

See the following example.

WAComplexRoute
        get: '/{3}/_all_docs?startkey={1}&limit={2}'
        selector: #getAllDocumentsStartingAt:limitedTo:inDatabase:
marschall commented 5 years ago

There isn't really anything that we can do if we do not have the method argument names.

ThomasBrodt commented 5 years ago

You can match parameters by index instead of names that way, but the default pragma resolution still calls getSource before testing for indexes instead of names and runs into an error.

createComplexRoute
    ^ WAComplexRoute
        method: method selector: compiled selector pattern: path
        arguments: (GRPlatform current argumentNamesOf: compiled)
        produces: produces
        consumes: (self createMimeTypeMatch: consumes)

in argumentNamesOf: getSource is invoked, which returns nil and the parsing for parameter names fails.

With the following snippet, I get an error with seaside 3.2 in visualworks 8.3.1 although I use indexes instead of parameter name matching

jsonForDate: aDate list: aList  
    <get>
    <path: '/list?date={1}&unitList={2}'>
    <produces: 'text/json'>

I think you should test for missing source before calling argumentNamesOf:. If you provide an empty collection as argumentNames if there is no source and you only have indexes in the path, the following code works (not pretty, but functional).

createComplexRoute
    | args |
    args := compiled getSource ifNil: [#()] ifNotNil: [GRPlatform current argumentNamesOf: compiled].
    ^ WAComplexRoute
        method: method
        selector: compiled selector
        pattern: path
        arguments: args
        produces: produces
        consumes: (self createMimeTypeMatch: consumes)