I am working on a new REST based API, starting with an alternative of `gerrit ls-projects` on HTTP. Internally its the same code, and the same options are supported on both.
--all : display all projects that are accessible by the calling user --description (-d) : include description of project in list --format FMT : Output display format --help (-h) : display this help text --limit CNT : maximum number of projects to list --show-branch (-b) VAL : displays the sha of each project in the specified branch --tree (-t) : displays project inheritance in a tree-like format this option does not work together with the show-branch option --type [CODE | PERMISSIONS | ALL] : type of project
> I am working on a new REST based API, starting with an alternative of > `gerrit ls-projects` on HTTP. Internally its the same code, and the > same options are supported on both.
> --all : display all projects that are accessible > by the calling user > --description (-d) : include description of project in list > --format FMT : Output display format > --help (-h) : display this help text > --limit CNT : maximum number of projects to list > --show-branch (-b) VAL : displays the sha of each project in the > specified branch > --tree (-t) : displays project inheritance in a > tree-like format > this option does not work together with > the show-branch option > --type [CODE | PERMISSIONS | ALL] : type of project
Some tools are better than others at allowing you populate http headers - in particular if you want to do a quick test in a web server being able to specify the format in the url is very useful..
> -----Original Message----- > From: repo-discuss@googlegroups.com [mailto:repo- > discuss@googlegroups.com] On Behalf Of Luca Milanesio > Sent: 05 April 2012 07:08 > To: Shawn Pearce > Cc: repo-discuss > Subject: Re: new REST API
> A couple of thoughts:
> - like the max num of items: can we have a skip as well ? > - accepted format: why not using the standard Accept HTTP header ?
> Overall +1 from me
> Luca > --------- > Sent from my iPhone > Luca Milanesio > Skype: lucamilanesio
> On 5 Apr 2012, at 06:25, Shawn Pearce <s...@google.com> wrote:
> > I am working on a new REST based API, starting with an alternative of > > `gerrit ls-projects` on HTTP. Internally its the same code, and the > > same options are supported on both.
> > --all : display all projects that are accessible > > by the calling user > > --description (-d) : include description of project in list > > --format FMT : Output display format > > --help (-h) : display this help text > > --limit CNT : maximum number of projects to list > > --show-branch (-b) VAL : displays the sha of each project in the > > specified branch > > --tree (-t) : displays project inheritance in a > > tree-like format > > this option does not work together with > > the show-branch option --type > > [CODE | PERMISSIONS | ALL] : type of project
*************************************************************************** *********** This message is confidential and intended only for the addressee. If you have received this message in error, please immediately notify the postmas...@nds.com and delete it from your system as well as any copies. The content of e-mails as well as traffic data may be monitored by NDS for employment and security purposes. To protect the environment please do not print this e-mail unless necessary.
NDS Limited. Registered Office: One London Road, Staines, Middlesex, TW18 4EX, United Kingdom. A company registered in England and Wales. Registered no. 3080780. VAT no. GB 603 8808 40-00 *************************************************************************** ***********
On Thursday, April 5, 2012 10:54:19 AM UTC+2, Thomas Swindells wrote:
> Some tools are better than others at allowing you populate http headers - > in particular if you want to do a quick test in a web server being able to > specify the format in the url is very useful..
From: repo-discuss@googlegroups.com [mailto:repo-discuss@googlegroups.com] On Behalf Of Thomas Broyer Sent: 05 April 2012 10:23 To: repo-discuss@googlegroups.com Cc: Luca Milanesio; Shawn Pearce Subject: Re: new REST API
On Thursday, April 5, 2012 10:54:19 AM UTC+2, Thomas Swindells wrote:
Some tools are better than others at allowing you populate http headers - in particular if you want to do a quick test in a web server being able to specify the format in the url is very useful..
*************************************************************************** *********** This message is confidential and intended only for the addressee. If you have received this message in error, please immediately notify the postmas...@nds.com and delete it from your system as well as any copies. The content of e-mails as well as traffic data may be monitored by NDS for employment and security purposes. To protect the environment please do not print this e-mail unless necessary.
NDS Limited. Registered Office: One London Road, Staines, Middlesex, TW18 4EX, United Kingdom. A company registered in England and Wales. Registered no. 3080780. VAT no. GB 603 8808 40-00 *************************************************************************** ***********
On Thu, Apr 5, 2012 at 02:07, Luca Milanesio <luca.milane...@gmail.com> wrote: > A couple of thoughts:
> - like the max num of items: can we have a skip as well ?
Skip seems stupid to me? Pagination is harmful and all that?
> - accepted format: why not using the standard Accept HTTP header ?
Already supported. "Accept: application/json" will trigger the JSON output. The format=JSON query parameter is a side effect of the fact that the change also adds a --format=JSON parameter to the `gerrit ls-projects` SSH command. Since the command options and the query parameters are the same thing, you get the format field either way.
The web UI client sets the Accept header to trigger JSON rather than using the format query parameter.
> On Thu, Apr 5, 2012 at 02:07, Luca Milanesio <luca.milane...@gmail.com> wrote: >> A couple of thoughts:
>> - like the max num of items: can we have a skip as well ?
> Skip seems stupid to me? Pagination is harmful and all that?
>> - accepted format: why not using the standard Accept HTTP header ?
> Already supported. "Accept: application/json" will trigger the JSON > output. The format=JSON query parameter is a side effect of the fact > that the change also adds a --format=JSON parameter to the `gerrit > ls-projects` SSH command. Since the command options and the query > parameters are the same thing, you get the format field either way.
> The web UI client sets the Accept header to trigger JSON rather than > using the format query parameter.
On Wed, Apr 4, 2012 at 22:25, Shawn Pearce <s...@google.com> wrote: > I am working on a new REST based API, starting with an alternative of > `gerrit ls-projects` on HTTP. Internally its the same code, and the > same options are supported on both.
Today I tried to replace /query. The /query API isn't really compatible with the new /projects/ API, so I wanted to start rebuilding it in a way that the HTML UI can use.
The query string is taken in the path info portion of the URL, which combined with the default query parsing logic makes for a reasonable REST API when accessing projects by name:
More normal query strings may seem odd, as the slashes in project, branch and topic names are not escaped so they appear to form oddly named directories in the URI space of the server:
That is, each "AND" operator in the query (which is implicit between query operators) turns into a directory in the /changes/ URI space and slashes in operator arguments like tools/repo have to be encoded as %2F to be parsed correctly by the server. The nice thing here is you can envision each new directory component in the URI as adding a further refinement over the contents of the previous directory, just like a UNIX filesystem would be doing for you when looking at the output of a recursive `find` command. :-)
Using / to mean "AND" (or really space between terms) breaks the example above, as the query would be parsed as "tools repo". Instead the example above would need to be:
/changes/tools%2Frepo?n=2&format=JSON
Which is a bit more awkward to work with. It certainly breaks any expectation of this being a REST-ful API centered around the major project entity in Gerrit Code Review. Finally, using something like OR in the query would break "directory semantics", because in our query language OR has a higher precedence than AND. "project:foo branch:master OR project:bar" only applies the branch:master filter to changes in project foo, all branches from bar are returned. The URI written as:
/changes/project:foo/branch:master+OR+project+bar
Doesn't read well to me for this concept of limiting the space and there really isn't a way around it.
We could use the query parameter approach like /query does:
But then this feels a bit less REST-ful to me. Maybe whether or not the path info portion of /changes/ gets used should depend on what the input string was? If it was a bare string with no operator, e.g. "tools/repo", it goes in path info and otherwise it should go into the q parameter?
URIs are opaque handles, so it's no more or less "REST-ful" than without a query-string (and if you ask me, when it comes to querying, I actually prefer having a query-string).
Maybe whether or not
> the path info portion of /changes/ gets used should depend on what the
> input string was? If it was a bare string with no operator, e.g.
> "tools/repo", it goes in path info and otherwise it should go into the
> q parameter?
That'd be great!
Actually, I don't really mind what the Web client uses; what matters most is what the server accepts.
How about simply appending the path info and "q" query-string parameter and using this as the query? That'd allow things like:
/changes/tools/repo?q=status:open&n=2&format=JSON
while keeping things simple (ideally, I'd also like the path-info to be parsed as a defaultField –and thus rule out /changes/is:watched?q=status:open– but that's probably too big a change)
Alternatively, the path-info could be transformed into "(project:path/info OR topic:path/info)" –or simply "project:path/info"– before prepending it to the "q".
> URIs are opaque handles, so it's no more or less "REST-ful" than without a > query-string (and if you ask me, when it comes to querying, I actually > prefer having a query-string).
>> Maybe whether or not >> the path info portion of /changes/ gets used should depend on what the >> input string was? If it was a bare string with no operator, e.g. >> "tools/repo", it goes in path info and otherwise it should go into the >> q parameter?
> That'd be great!
> Actually, I don't really mind what the Web client uses; what matters most is > what the server accepts.
Well, the biggest example of the API usage will be the web client. People are going to open the developer tools panel in their browser, look at the XHR requests the browser makes, and emulate that in their own tools. Especially when they learn that the web client uses stable APIs that are fairly simple to use (compared to the current JSON-RPC mess we have).
> How about simply appending the path info and "q" query-string parameter and > using this as the query? That'd allow things like:
That is a good idea. It might be hard to do from the web UI to find the single default field (if one exists) and promote it to the path info portion. But its certainly easy to AND the path info with the q parameter inside of the server.
> while keeping things simple (ideally, I'd also like the path-info to be > parsed as a defaultField –and thus rule out > /changes/is:watched?q=status:open– but that's probably too big a change)
Actually its not. If we say the path info must be a *single* default field term, that is "tools/repo" and not "tools/repo+master", we can parse the path info with the default field function, get its Predicate<ChangeData>, then AND that with the parse of the q parameter string and execute that expression. This is fairly simple.
> Alternatively, the path-info could be transformed into "(project:path/info > OR topic:path/info)" –or simply "project:path/info"– before prepending it to > the "q".
No, I would prefer to parse it as either its own expression or defaultField, then AND that with the entire q parameter. Its more logical than simply prepending due to the OR operator (though that is obviously fixable by wrapping the q parameter in parens when we prepend, but its just cleaner internally to parse twice and join the two nodes of the tree with the AND operator after parsing).
I think what you are trying to say here is we parse the query string by converting & to mean " AND " in our query language, and | to mean " OR "?
If I do this it limits what we can communicate to the server. Everything has to be inside of the query language if we want to send it to the /changes/ handler. For example, the format=TEXT|JSON output option is no longer available unless I add a predicate to the query language called "output_format" that has no bearing on the match, but tells us how to produce the output. This of course gets funny when the user asks for "project:foo&output_format=JSON|project:bar&output_format=TEXT", the intent seems to say "produce results for foo in JSON and results for bar in TEXT" but of course this is nonsense and can't be honored as written.
I also don't like the idea that we are making & and | synonyms with the existing "space" or "AND" keyword and "OR" keywords in the query language. In my mind, to correctly support & and | to have these meanings in the query string, we should actually add them to Query.g as alternatives for the existing boolean operators and allow users to type these into the web search box. Which few users will do, its a grottier looking syntax than what we use now.
>> while keeping things simple (ideally, I'd also like the path-info to be >> parsed as a defaultField –and thus rule out >> /changes/is:watched?q=status:open– but that's probably too big a change)
> Actually its not. If we say the path info must be a *single* default > field term, that is "tools/repo" and not "tools/repo+master", we can > parse the path info with the default field function, get its > Predicate<ChangeData>, then AND that with the parse of the q parameter > string and execute that expression. This is fairly simple.
This is now done in my latest patch set (just pushed).
I also taught the /changes/ server to report back label information dynamically from the project rules, which means I was also able to update the GWT UI so the changes table used to display All > Open shows V and CR columns based on what the Prolog rules say are actually required, rather than just what the server administrator put into the database.
>>> while keeping things simple (ideally, I'd also like the path-info to be >>> parsed as a defaultField –and thus rule out >>> /changes/is:watched?q=status:open– but that's probably too big a change)
>> Actually its not. If we say the path info must be a *single* default >> field term, that is "tools/repo" and not "tools/repo+master", we can >> parse the path info with the default field function, get its >> Predicate<ChangeData>, then AND that with the parse of the q parameter >> string and execute that expression. This is fairly simple.
> This is now done in my latest patch set (just pushed).
> I also taught the /changes/ server to report back label information > dynamically from the project rules, which means I was also able to > update the GWT UI so the changes table used to display All > Open > shows V and CR columns based on what the Prolog rules say are actually > required, rather than just what the server administrator put into the > database.