You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@trafficcontrol.apache.org by Jeremy Mitchell <mi...@apache.org> on 2018/04/03 21:26:38 UTC

Updated TO API guidelines

FYI - I've updated the TO API guidelines to reflect our desire to move away
from route/path params and embrace query params in the Golang API.

https://cwiki.apache.org/confluence/display/TC/API+Guidelines

Jeremy

Re: Updated TO API guidelines

Posted by Robert Butts <ro...@gmail.com>.
Ah, sorry, I misunderstood. I thought when you said "a route that never
existed in 1.2 before" you meant e.g. /api/1.3/servers "didn't exist in
Golang or 1.3 before".

Right, for entirely new routes, e.g. deliveryservices/{xmlID}/urisignkeys,
path params are fine, and still conform to SemVer for the same major
version, e.g. 1.3.


On Wed, Apr 4, 2018 at 4:12 PM, Robert Butts <ro...@gmail.com>
wrote:

> You're right, in our code today, we don't use raw major versions
> (/api/1/foo) in our API, and our clients have hard-coded minor versions.
>
> If we feel like that's how we want to design APIs and clients, and say
> "our minor versions are not compatible with each-other", we can do that.
> But it's not Semantic Versioning.
>
> Semantic Versioning says: (semver.org)
> > MAJOR version when you make incompatible API changes,
> > MINOR version when you add functionality in a backwards-compatible manner
>
> Even if our current code doesn't strictly need SemVer, using a well-known
> standard makes it easier to understand. People know at a glance which
> versions are compatible, which have changed, and when they need to go read
> the docs again. Maybe someone else wants to write their own TO client, that
> expects SemVer.
>
> Is there a disadvantage to using SemVer? Even if we want to break
> backwards compatibility, we can just keep rolling major versions, /api/2/,
> /api/3/, /api/42/. I'd rather we didn't break compatibility so often, but
> if we do, there's no harm in the number itself.
>
>
> On Wed, Apr 4, 2018 at 4:00 PM, Volz, Dylan <Dy...@comcast.com>
> wrote:
>
>> " a request from a client which is built to understand say /api/1.2/, if
>>     that same request is made to /api/1.3/, it should still work."
>>
>> But this is a route that never existed in 1.2 before, not a new version
>> of a route in 1.3,
>> a client built to understand 1.2 will just not have this route at all and
>> would require
>>  new dev work to support, or maybe I am misunderstanding you?
>>
>> On 4/4/18, 3:49 PM, "Robert Butts" <ro...@gmail.com> wrote:
>>
>>     >Technically, adding new routes does not  break old stuff right so i
>> don't
>>     think that warrants a major version roll.
>>
>>     New routes that use query params instead of path params will
>> definitely
>>     break old stuff.
>>
>>     When you say "break old stuff", the idea behind Semantic Versioning,
>> is
>>     that a request from a client which is built to understand say
>> /api/1.2/, if
>>     that same request is made to /api/1.3/, it should still work. If not,
>> it's
>>     not Semantic Versioning.
>>
>>     That also allows you to serve your latest minor version at /api/1/,
>>     /api/2/, etc, and clients who know the Server is newer than them can
>> hit
>>     the major endpoint, and be guaranteed to work. We don't currently do
>> that,
>>     but it'd be nice if we did.
>>
>>     I'm +1 on query params, but also +1 on https://semver.org/
>>
>>
>>     On Wed, Apr 4, 2018 at 3:23 PM, Jeremy Mitchell <
>> mitchell852@gmail.com>
>>     wrote:
>>
>>     > tbh i'm not sure about versioning. I was just trying to suggest
>> that new
>>     > routes be formulated this way per the new API guidelines:
>>     >
>>     > GET /foos[?id, name, etc=]
>>     > POST /foos
>>     > PUT /foos [?id, name, etc=]
>>     > DELETE /foos [?id, name, etc=]
>>     >
>>     > instead of the old way:
>>     >
>>     > GET /foos
>>     > GET /foos/:id
>>     > POST /foos
>>     > PUT /foos/:id
>>     > DELETE /foos/:id
>>     >
>>     > The difference being the use of query params over route/path params.
>>     >
>>     > Technically, adding new routes does not break old stuff right so i
>> don't
>>     > think that warrants a major version roll.
>>     >
>>     > While we're on the subject, what does everyone think if we took
>> this one
>>     > step further and made routes handle a request payload with one or
>> more
>>     > items. For example:
>>     >
>>     > GET /foos[?id, name, etc=]
>>     > POST /foos <-- takes in an array of foos to create
>>     > PUT /foos <-- takes in an array of foos to update
>>     > DELETE /foos <-- takes in an array of foos to delete
>>     >
>>     > in this scenario, query params only pertain to the GET. The POST,
>> PUT and
>>     > DELETE rely on the contents of the request json...
>>     >
>>     > Jeremy
>>     >
>>     >
>>     >
>>     >
>>     >
>>     >
>>     >
>>     >
>>     >
>>     >
>>     >
>>     > On Wed, Apr 4, 2018 at 1:55 PM, Robert Butts <
>> robert.o.butts@gmail.com>
>>     > wrote:
>>     >
>>     > > That document doesn't mention versions, 1.2 vs 1.3 vs 2.0.
>>     > >
>>     > > Just to clarify, changing to query parameters breaks
>> compatibility with
>>     > 1.2
>>     > > and older, so new APIs in that format have to be a new major
>> version,
>>     > i.e.
>>     > > 2.0, per Semantic Versioning, right?
>>     > >
>>     > > On Tue, Apr 3, 2018 at 3:26 PM, Jeremy Mitchell <
>> mitchell852@apache.org>
>>     > > wrote:
>>     > >
>>     > > > FYI - I've updated the TO API guidelines to reflect our desire
>> to move
>>     > > away
>>     > > > from route/path params and embrace query params in the Golang
>> API.
>>     > > >
>>     > > > https://cwiki.apache.org/confluence/display/TC/API+Guidelines
>>     > > >
>>     > > > Jeremy
>>     > > >
>>     > >
>>     >
>>
>>
>>
>

Re: Updated TO API guidelines

Posted by Robert Butts <ro...@gmail.com>.
You're right, in our code today, we don't use raw major versions
(/api/1/foo) in our API, and our clients have hard-coded minor versions.

If we feel like that's how we want to design APIs and clients, and say "our
minor versions are not compatible with each-other", we can do that. But
it's not Semantic Versioning.

Semantic Versioning says: (semver.org)
> MAJOR version when you make incompatible API changes,
> MINOR version when you add functionality in a backwards-compatible manner

Even if our current code doesn't strictly need SemVer, using a well-known
standard makes it easier to understand. People know at a glance which
versions are compatible, which have changed, and when they need to go read
the docs again. Maybe someone else wants to write their own TO client, that
expects SemVer.

Is there a disadvantage to using SemVer? Even if we want to break backwards
compatibility, we can just keep rolling major versions, /api/2/, /api/3/,
/api/42/. I'd rather we didn't break compatibility so often, but if we do,
there's no harm in the number itself.


On Wed, Apr 4, 2018 at 4:00 PM, Volz, Dylan <Dy...@comcast.com> wrote:

> " a request from a client which is built to understand say /api/1.2/, if
>     that same request is made to /api/1.3/, it should still work."
>
> But this is a route that never existed in 1.2 before, not a new version of
> a route in 1.3,
> a client built to understand 1.2 will just not have this route at all and
> would require
>  new dev work to support, or maybe I am misunderstanding you?
>
> On 4/4/18, 3:49 PM, "Robert Butts" <ro...@gmail.com> wrote:
>
>     >Technically, adding new routes does not  break old stuff right so i
> don't
>     think that warrants a major version roll.
>
>     New routes that use query params instead of path params will definitely
>     break old stuff.
>
>     When you say "break old stuff", the idea behind Semantic Versioning, is
>     that a request from a client which is built to understand say
> /api/1.2/, if
>     that same request is made to /api/1.3/, it should still work. If not,
> it's
>     not Semantic Versioning.
>
>     That also allows you to serve your latest minor version at /api/1/,
>     /api/2/, etc, and clients who know the Server is newer than them can
> hit
>     the major endpoint, and be guaranteed to work. We don't currently do
> that,
>     but it'd be nice if we did.
>
>     I'm +1 on query params, but also +1 on https://semver.org/
>
>
>     On Wed, Apr 4, 2018 at 3:23 PM, Jeremy Mitchell <mitchell852@gmail.com
> >
>     wrote:
>
>     > tbh i'm not sure about versioning. I was just trying to suggest that
> new
>     > routes be formulated this way per the new API guidelines:
>     >
>     > GET /foos[?id, name, etc=]
>     > POST /foos
>     > PUT /foos [?id, name, etc=]
>     > DELETE /foos [?id, name, etc=]
>     >
>     > instead of the old way:
>     >
>     > GET /foos
>     > GET /foos/:id
>     > POST /foos
>     > PUT /foos/:id
>     > DELETE /foos/:id
>     >
>     > The difference being the use of query params over route/path params.
>     >
>     > Technically, adding new routes does not break old stuff right so i
> don't
>     > think that warrants a major version roll.
>     >
>     > While we're on the subject, what does everyone think if we took this
> one
>     > step further and made routes handle a request payload with one or
> more
>     > items. For example:
>     >
>     > GET /foos[?id, name, etc=]
>     > POST /foos <-- takes in an array of foos to create
>     > PUT /foos <-- takes in an array of foos to update
>     > DELETE /foos <-- takes in an array of foos to delete
>     >
>     > in this scenario, query params only pertain to the GET. The POST,
> PUT and
>     > DELETE rely on the contents of the request json...
>     >
>     > Jeremy
>     >
>     >
>     >
>     >
>     >
>     >
>     >
>     >
>     >
>     >
>     >
>     > On Wed, Apr 4, 2018 at 1:55 PM, Robert Butts <
> robert.o.butts@gmail.com>
>     > wrote:
>     >
>     > > That document doesn't mention versions, 1.2 vs 1.3 vs 2.0.
>     > >
>     > > Just to clarify, changing to query parameters breaks compatibility
> with
>     > 1.2
>     > > and older, so new APIs in that format have to be a new major
> version,
>     > i.e.
>     > > 2.0, per Semantic Versioning, right?
>     > >
>     > > On Tue, Apr 3, 2018 at 3:26 PM, Jeremy Mitchell <
> mitchell852@apache.org>
>     > > wrote:
>     > >
>     > > > FYI - I've updated the TO API guidelines to reflect our desire
> to move
>     > > away
>     > > > from route/path params and embrace query params in the Golang
> API.
>     > > >
>     > > > https://cwiki.apache.org/confluence/display/TC/API+Guidelines
>     > > >
>     > > > Jeremy
>     > > >
>     > >
>     >
>
>
>

Re: Updated TO API guidelines

Posted by "Volz, Dylan" <Dy...@comcast.com>.
" a request from a client which is built to understand say /api/1.2/, if
    that same request is made to /api/1.3/, it should still work."

But this is a route that never existed in 1.2 before, not a new version of a route in 1.3, 
a client built to understand 1.2 will just not have this route at all and would require
 new dev work to support, or maybe I am misunderstanding you?

On 4/4/18, 3:49 PM, "Robert Butts" <ro...@gmail.com> wrote:

    >Technically, adding new routes does not  break old stuff right so i don't
    think that warrants a major version roll.
    
    New routes that use query params instead of path params will definitely
    break old stuff.
    
    When you say "break old stuff", the idea behind Semantic Versioning, is
    that a request from a client which is built to understand say /api/1.2/, if
    that same request is made to /api/1.3/, it should still work. If not, it's
    not Semantic Versioning.
    
    That also allows you to serve your latest minor version at /api/1/,
    /api/2/, etc, and clients who know the Server is newer than them can hit
    the major endpoint, and be guaranteed to work. We don't currently do that,
    but it'd be nice if we did.
    
    I'm +1 on query params, but also +1 on https://semver.org/
    
    
    On Wed, Apr 4, 2018 at 3:23 PM, Jeremy Mitchell <mi...@gmail.com>
    wrote:
    
    > tbh i'm not sure about versioning. I was just trying to suggest that new
    > routes be formulated this way per the new API guidelines:
    >
    > GET /foos[?id, name, etc=]
    > POST /foos
    > PUT /foos [?id, name, etc=]
    > DELETE /foos [?id, name, etc=]
    >
    > instead of the old way:
    >
    > GET /foos
    > GET /foos/:id
    > POST /foos
    > PUT /foos/:id
    > DELETE /foos/:id
    >
    > The difference being the use of query params over route/path params.
    >
    > Technically, adding new routes does not break old stuff right so i don't
    > think that warrants a major version roll.
    >
    > While we're on the subject, what does everyone think if we took this one
    > step further and made routes handle a request payload with one or more
    > items. For example:
    >
    > GET /foos[?id, name, etc=]
    > POST /foos <-- takes in an array of foos to create
    > PUT /foos <-- takes in an array of foos to update
    > DELETE /foos <-- takes in an array of foos to delete
    >
    > in this scenario, query params only pertain to the GET. The POST, PUT and
    > DELETE rely on the contents of the request json...
    >
    > Jeremy
    >
    >
    >
    >
    >
    >
    >
    >
    >
    >
    >
    > On Wed, Apr 4, 2018 at 1:55 PM, Robert Butts <ro...@gmail.com>
    > wrote:
    >
    > > That document doesn't mention versions, 1.2 vs 1.3 vs 2.0.
    > >
    > > Just to clarify, changing to query parameters breaks compatibility with
    > 1.2
    > > and older, so new APIs in that format have to be a new major version,
    > i.e.
    > > 2.0, per Semantic Versioning, right?
    > >
    > > On Tue, Apr 3, 2018 at 3:26 PM, Jeremy Mitchell <mi...@apache.org>
    > > wrote:
    > >
    > > > FYI - I've updated the TO API guidelines to reflect our desire to move
    > > away
    > > > from route/path params and embrace query params in the Golang API.
    > > >
    > > > https://cwiki.apache.org/confluence/display/TC/API+Guidelines
    > > >
    > > > Jeremy
    > > >
    > >
    >
    


Re: Updated TO API guidelines

Posted by Robert Butts <ro...@gmail.com>.
>Technically, adding new routes does not  break old stuff right so i don't
think that warrants a major version roll.

New routes that use query params instead of path params will definitely
break old stuff.

When you say "break old stuff", the idea behind Semantic Versioning, is
that a request from a client which is built to understand say /api/1.2/, if
that same request is made to /api/1.3/, it should still work. If not, it's
not Semantic Versioning.

That also allows you to serve your latest minor version at /api/1/,
/api/2/, etc, and clients who know the Server is newer than them can hit
the major endpoint, and be guaranteed to work. We don't currently do that,
but it'd be nice if we did.

I'm +1 on query params, but also +1 on https://semver.org/


On Wed, Apr 4, 2018 at 3:23 PM, Jeremy Mitchell <mi...@gmail.com>
wrote:

> tbh i'm not sure about versioning. I was just trying to suggest that new
> routes be formulated this way per the new API guidelines:
>
> GET /foos[?id, name, etc=]
> POST /foos
> PUT /foos [?id, name, etc=]
> DELETE /foos [?id, name, etc=]
>
> instead of the old way:
>
> GET /foos
> GET /foos/:id
> POST /foos
> PUT /foos/:id
> DELETE /foos/:id
>
> The difference being the use of query params over route/path params.
>
> Technically, adding new routes does not break old stuff right so i don't
> think that warrants a major version roll.
>
> While we're on the subject, what does everyone think if we took this one
> step further and made routes handle a request payload with one or more
> items. For example:
>
> GET /foos[?id, name, etc=]
> POST /foos <-- takes in an array of foos to create
> PUT /foos <-- takes in an array of foos to update
> DELETE /foos <-- takes in an array of foos to delete
>
> in this scenario, query params only pertain to the GET. The POST, PUT and
> DELETE rely on the contents of the request json...
>
> Jeremy
>
>
>
>
>
>
>
>
>
>
>
> On Wed, Apr 4, 2018 at 1:55 PM, Robert Butts <ro...@gmail.com>
> wrote:
>
> > That document doesn't mention versions, 1.2 vs 1.3 vs 2.0.
> >
> > Just to clarify, changing to query parameters breaks compatibility with
> 1.2
> > and older, so new APIs in that format have to be a new major version,
> i.e.
> > 2.0, per Semantic Versioning, right?
> >
> > On Tue, Apr 3, 2018 at 3:26 PM, Jeremy Mitchell <mi...@apache.org>
> > wrote:
> >
> > > FYI - I've updated the TO API guidelines to reflect our desire to move
> > away
> > > from route/path params and embrace query params in the Golang API.
> > >
> > > https://cwiki.apache.org/confluence/display/TC/API+Guidelines
> > >
> > > Jeremy
> > >
> >
>

Re: Updated TO API guidelines

Posted by Jeremy Mitchell <mi...@gmail.com>.
@dave - you're right. the PR referenced above did not update version, docs
or tests.

re: version - these were very new endpoints. i simply rewrote it to follow
the new api guidelines. i think the risk of doing that was low as TP is the
only consumer of this endpoint.
re: docs - docs for 1.3 endpoints haven't been written. we're going to
depend on swagger for that. right dewayne?
re: tests - yep, i failed to update the existing tests and broke them and
submitted this subsequent PR -
https://github.com/apache/incubator-trafficcontrol/pull/2106

@rawlin -

i agree. i'd love to dump support for the `?(.json) ` suffix. seems
redundant. i would suggest that any new GET routes don't include it.

On Mon, Apr 9, 2018 at 12:02 PM, Rawlin Peters <ra...@gmail.com>
wrote:

> Thanks for the example, Jeremy. Do we have any guidelines about
> whether or not the `?(.json) ` suffix should be supported for new API
> endpoints? It seems pointless because the API will always return JSON.
>
> - Rawlin
>
> On Fri, Apr 6, 2018 at 3:14 PM, Jeremy Mitchell <mi...@gmail.com>
> wrote:
> > Rawlin,
> >
> > I have submitted a PR to change some new ds request routes to utilize
> query
> > params instead of path/route params (the legacy format):
> >
> > https://github.com/apache/incubator-trafficcontrol/pull/2094
> >
> > On Fri, Apr 6, 2018 at 11:59 AM, Rawlin Peters <ra...@gmail.com>
> > wrote:
> >
> >> Do we currently have an example of an API endpoint written in the
> >> traffic_ops_golang framework that uses only query parameters like
> >> this? How would it compare to the legacy format?
> >>
> >> -Rawlin
> >>
> >> On Thu, Apr 5, 2018 at 9:45 AM, Dewayne Richardson <de...@apache.org>
> >> wrote:
> >> > Thank you John for giving us "API Use Cases" to think about with these
> >> new
> >> > TO API Guidelines.  The main goal for these changes are to build TO
> API's
> >> > that are intuitive.  I'm of the opinion that if the API's are
> intuitive
> >> > (with easy to understand patterns) that prevents me from wasting time
> >> > looking up API docs.  A nice side effect of having simple standards
> and
> >> > patterns is that simplicity ripples into our API Go code which allows
> us
> >> to
> >> > easily build frameworks that do all of the work instead of the API
> >> > snowflakes that we have today.
> >> >
> >> > I encourage everyone to shoot as many holes into our thoughts around
> this
> >> > new direction so that we can see the bigger picture.
> >> >
> >> > -Dew
> >> >
> >> > On Wed, Apr 4, 2018 at 10:29 PM, John Rushford <jj...@gmail.com>
> >> wrote:
> >> >
> >> >> Why the change?  It’s my understanding that path parameters should be
> >> used
> >> >> to specify a particular resource
> >> >> and query parameters should be used to sort/filter the query.  Why
> use a
> >> >> query parameter to specify a particular
> >> >> resource?  Is this REST API best practice?
> >> >>
> >> >> What about sub resource queries such as using the following:
> >> >>
> >> >> GET api/1.3/deliveryservices/{xmlID}/urisigning
> >> >>
> >> >> where you are requesting a particular urisigning keys sub resource
> for
> >> the
> >> >> particular deliveryservice resource. You can make it work
> >> >> with an xmlid query parameter but what do you return if the query
> >> >> parameter is left off, all uri signing keys?  Is that useful?
> >> >>
> >> >> John
> >> >>
> >> >> > On Apr 4, 2018, at 3:23 PM, Jeremy Mitchell <mitchell852@gmail.com
> >
> >> >> wrote:
> >> >> >
> >> >> > tbh i'm not sure about versioning. I was just trying to suggest
> that
> >> new
> >> >> > routes be formulated this way per the new API guidelines:
> >> >> >
> >> >> > GET /foos[?id, name, etc=]
> >> >> > POST /foos
> >> >> > PUT /foos [?id, name, etc=]
> >> >> > DELETE /foos [?id, name, etc=]
> >> >> >
> >> >> > instead of the old way:
> >> >> >
> >> >> > GET /foos
> >> >> > GET /foos/:id
> >> >> > POST /foos
> >> >> > PUT /foos/:id
> >> >> > DELETE /foos/:id
> >> >> >
> >> >> > The difference being the use of query params over route/path
> params.
> >> >> >
> >> >> > Technically, adding new routes does not break old stuff right so i
> >> don't
> >> >> > think that warrants a major version roll.
> >> >> >
> >> >> > While we're on the subject, what does everyone think if we took
> this
> >> one
> >> >> > step further and made routes handle a request payload with one or
> more
> >> >> > items. For example:
> >> >> >
> >> >> > GET /foos[?id, name, etc=]
> >> >> > POST /foos <-- takes in an array of foos to create
> >> >> > PUT /foos <-- takes in an array of foos to update
> >> >> > DELETE /foos <-- takes in an array of foos to delete
> >> >> >
> >> >> > in this scenario, query params only pertain to the GET. The POST,
> PUT
> >> and
> >> >> > DELETE rely on the contents of the request json...
> >> >> >
> >> >> > Jeremy
> >> >> >
> >> >> >
> >> >> >
> >> >> >
> >> >> >
> >> >> >
> >> >> >
> >> >> >
> >> >> >
> >> >> >
> >> >> >
> >> >> > On Wed, Apr 4, 2018 at 1:55 PM, Robert Butts <
> >> robert.o.butts@gmail.com>
> >> >> > wrote:
> >> >> >
> >> >> >> That document doesn't mention versions, 1.2 vs 1.3 vs 2.0.
> >> >> >>
> >> >> >> Just to clarify, changing to query parameters breaks compatibility
> >> with
> >> >> 1.2
> >> >> >> and older, so new APIs in that format have to be a new major
> version,
> >> >> i.e.
> >> >> >> 2.0, per Semantic Versioning, right?
> >> >> >>
> >> >> >> On Tue, Apr 3, 2018 at 3:26 PM, Jeremy Mitchell <
> >> mitchell852@apache.org
> >> >> >
> >> >> >> wrote:
> >> >> >>
> >> >> >>> FYI - I've updated the TO API guidelines to reflect our desire to
> >> move
> >> >> >> away
> >> >> >>> from route/path params and embrace query params in the Golang
> API.
> >> >> >>>
> >> >> >>> https://cwiki.apache.org/confluence/display/TC/API+Guidelines
> >> >> >>>
> >> >> >>> Jeremy
> >> >> >>>
> >> >> >>
> >> >>
> >> >>
> >>
>

Re: Updated TO API guidelines

Posted by Rawlin Peters <ra...@gmail.com>.
Thanks for the example, Jeremy. Do we have any guidelines about
whether or not the `?(.json) ` suffix should be supported for new API
endpoints? It seems pointless because the API will always return JSON.

- Rawlin

On Fri, Apr 6, 2018 at 3:14 PM, Jeremy Mitchell <mi...@gmail.com> wrote:
> Rawlin,
>
> I have submitted a PR to change some new ds request routes to utilize query
> params instead of path/route params (the legacy format):
>
> https://github.com/apache/incubator-trafficcontrol/pull/2094
>
> On Fri, Apr 6, 2018 at 11:59 AM, Rawlin Peters <ra...@gmail.com>
> wrote:
>
>> Do we currently have an example of an API endpoint written in the
>> traffic_ops_golang framework that uses only query parameters like
>> this? How would it compare to the legacy format?
>>
>> -Rawlin
>>
>> On Thu, Apr 5, 2018 at 9:45 AM, Dewayne Richardson <de...@apache.org>
>> wrote:
>> > Thank you John for giving us "API Use Cases" to think about with these
>> new
>> > TO API Guidelines.  The main goal for these changes are to build TO API's
>> > that are intuitive.  I'm of the opinion that if the API's are intuitive
>> > (with easy to understand patterns) that prevents me from wasting time
>> > looking up API docs.  A nice side effect of having simple standards and
>> > patterns is that simplicity ripples into our API Go code which allows us
>> to
>> > easily build frameworks that do all of the work instead of the API
>> > snowflakes that we have today.
>> >
>> > I encourage everyone to shoot as many holes into our thoughts around this
>> > new direction so that we can see the bigger picture.
>> >
>> > -Dew
>> >
>> > On Wed, Apr 4, 2018 at 10:29 PM, John Rushford <jj...@gmail.com>
>> wrote:
>> >
>> >> Why the change?  It’s my understanding that path parameters should be
>> used
>> >> to specify a particular resource
>> >> and query parameters should be used to sort/filter the query.  Why use a
>> >> query parameter to specify a particular
>> >> resource?  Is this REST API best practice?
>> >>
>> >> What about sub resource queries such as using the following:
>> >>
>> >> GET api/1.3/deliveryservices/{xmlID}/urisigning
>> >>
>> >> where you are requesting a particular urisigning keys sub resource for
>> the
>> >> particular deliveryservice resource. You can make it work
>> >> with an xmlid query parameter but what do you return if the query
>> >> parameter is left off, all uri signing keys?  Is that useful?
>> >>
>> >> John
>> >>
>> >> > On Apr 4, 2018, at 3:23 PM, Jeremy Mitchell <mi...@gmail.com>
>> >> wrote:
>> >> >
>> >> > tbh i'm not sure about versioning. I was just trying to suggest that
>> new
>> >> > routes be formulated this way per the new API guidelines:
>> >> >
>> >> > GET /foos[?id, name, etc=]
>> >> > POST /foos
>> >> > PUT /foos [?id, name, etc=]
>> >> > DELETE /foos [?id, name, etc=]
>> >> >
>> >> > instead of the old way:
>> >> >
>> >> > GET /foos
>> >> > GET /foos/:id
>> >> > POST /foos
>> >> > PUT /foos/:id
>> >> > DELETE /foos/:id
>> >> >
>> >> > The difference being the use of query params over route/path params.
>> >> >
>> >> > Technically, adding new routes does not break old stuff right so i
>> don't
>> >> > think that warrants a major version roll.
>> >> >
>> >> > While we're on the subject, what does everyone think if we took this
>> one
>> >> > step further and made routes handle a request payload with one or more
>> >> > items. For example:
>> >> >
>> >> > GET /foos[?id, name, etc=]
>> >> > POST /foos <-- takes in an array of foos to create
>> >> > PUT /foos <-- takes in an array of foos to update
>> >> > DELETE /foos <-- takes in an array of foos to delete
>> >> >
>> >> > in this scenario, query params only pertain to the GET. The POST, PUT
>> and
>> >> > DELETE rely on the contents of the request json...
>> >> >
>> >> > Jeremy
>> >> >
>> >> >
>> >> >
>> >> >
>> >> >
>> >> >
>> >> >
>> >> >
>> >> >
>> >> >
>> >> >
>> >> > On Wed, Apr 4, 2018 at 1:55 PM, Robert Butts <
>> robert.o.butts@gmail.com>
>> >> > wrote:
>> >> >
>> >> >> That document doesn't mention versions, 1.2 vs 1.3 vs 2.0.
>> >> >>
>> >> >> Just to clarify, changing to query parameters breaks compatibility
>> with
>> >> 1.2
>> >> >> and older, so new APIs in that format have to be a new major version,
>> >> i.e.
>> >> >> 2.0, per Semantic Versioning, right?
>> >> >>
>> >> >> On Tue, Apr 3, 2018 at 3:26 PM, Jeremy Mitchell <
>> mitchell852@apache.org
>> >> >
>> >> >> wrote:
>> >> >>
>> >> >>> FYI - I've updated the TO API guidelines to reflect our desire to
>> move
>> >> >> away
>> >> >>> from route/path params and embrace query params in the Golang API.
>> >> >>>
>> >> >>> https://cwiki.apache.org/confluence/display/TC/API+Guidelines
>> >> >>>
>> >> >>> Jeremy
>> >> >>>
>> >> >>
>> >>
>> >>
>>

Re: Updated TO API guidelines

Posted by Dave Neuman <ne...@apache.org>.
I am fine if we move in this direction, but I think we should be very
careful not to break existing functionality.  We need to make sure that if
we do change from path params to query params that we update our API
versions, documentation, and tests accordingly.
Unless I am reading it wrong, it looks like the PR mentioned above by
Jeremy is not updating the version, the docs, or any associated tests.

Thanks,
Dave

On Fri, Apr 6, 2018 at 3:14 PM, Jeremy Mitchell <mi...@gmail.com>
wrote:

> Rawlin,
>
> I have submitted a PR to change some new ds request routes to utilize query
> params instead of path/route params (the legacy format):
>
> https://github.com/apache/incubator-trafficcontrol/pull/2094
>
> On Fri, Apr 6, 2018 at 11:59 AM, Rawlin Peters <ra...@gmail.com>
> wrote:
>
> > Do we currently have an example of an API endpoint written in the
> > traffic_ops_golang framework that uses only query parameters like
> > this? How would it compare to the legacy format?
> >
> > -Rawlin
> >
> > On Thu, Apr 5, 2018 at 9:45 AM, Dewayne Richardson <de...@apache.org>
> > wrote:
> > > Thank you John for giving us "API Use Cases" to think about with these
> > new
> > > TO API Guidelines.  The main goal for these changes are to build TO
> API's
> > > that are intuitive.  I'm of the opinion that if the API's are intuitive
> > > (with easy to understand patterns) that prevents me from wasting time
> > > looking up API docs.  A nice side effect of having simple standards and
> > > patterns is that simplicity ripples into our API Go code which allows
> us
> > to
> > > easily build frameworks that do all of the work instead of the API
> > > snowflakes that we have today.
> > >
> > > I encourage everyone to shoot as many holes into our thoughts around
> this
> > > new direction so that we can see the bigger picture.
> > >
> > > -Dew
> > >
> > > On Wed, Apr 4, 2018 at 10:29 PM, John Rushford <jj...@gmail.com>
> > wrote:
> > >
> > >> Why the change?  It’s my understanding that path parameters should be
> > used
> > >> to specify a particular resource
> > >> and query parameters should be used to sort/filter the query.  Why
> use a
> > >> query parameter to specify a particular
> > >> resource?  Is this REST API best practice?
> > >>
> > >> What about sub resource queries such as using the following:
> > >>
> > >> GET api/1.3/deliveryservices/{xmlID}/urisigning
> > >>
> > >> where you are requesting a particular urisigning keys sub resource for
> > the
> > >> particular deliveryservice resource. You can make it work
> > >> with an xmlid query parameter but what do you return if the query
> > >> parameter is left off, all uri signing keys?  Is that useful?
> > >>
> > >> John
> > >>
> > >> > On Apr 4, 2018, at 3:23 PM, Jeremy Mitchell <mi...@gmail.com>
> > >> wrote:
> > >> >
> > >> > tbh i'm not sure about versioning. I was just trying to suggest that
> > new
> > >> > routes be formulated this way per the new API guidelines:
> > >> >
> > >> > GET /foos[?id, name, etc=]
> > >> > POST /foos
> > >> > PUT /foos [?id, name, etc=]
> > >> > DELETE /foos [?id, name, etc=]
> > >> >
> > >> > instead of the old way:
> > >> >
> > >> > GET /foos
> > >> > GET /foos/:id
> > >> > POST /foos
> > >> > PUT /foos/:id
> > >> > DELETE /foos/:id
> > >> >
> > >> > The difference being the use of query params over route/path params.
> > >> >
> > >> > Technically, adding new routes does not break old stuff right so i
> > don't
> > >> > think that warrants a major version roll.
> > >> >
> > >> > While we're on the subject, what does everyone think if we took this
> > one
> > >> > step further and made routes handle a request payload with one or
> more
> > >> > items. For example:
> > >> >
> > >> > GET /foos[?id, name, etc=]
> > >> > POST /foos <-- takes in an array of foos to create
> > >> > PUT /foos <-- takes in an array of foos to update
> > >> > DELETE /foos <-- takes in an array of foos to delete
> > >> >
> > >> > in this scenario, query params only pertain to the GET. The POST,
> PUT
> > and
> > >> > DELETE rely on the contents of the request json...
> > >> >
> > >> > Jeremy
> > >> >
> > >> >
> > >> >
> > >> >
> > >> >
> > >> >
> > >> >
> > >> >
> > >> >
> > >> >
> > >> >
> > >> > On Wed, Apr 4, 2018 at 1:55 PM, Robert Butts <
> > robert.o.butts@gmail.com>
> > >> > wrote:
> > >> >
> > >> >> That document doesn't mention versions, 1.2 vs 1.3 vs 2.0.
> > >> >>
> > >> >> Just to clarify, changing to query parameters breaks compatibility
> > with
> > >> 1.2
> > >> >> and older, so new APIs in that format have to be a new major
> version,
> > >> i.e.
> > >> >> 2.0, per Semantic Versioning, right?
> > >> >>
> > >> >> On Tue, Apr 3, 2018 at 3:26 PM, Jeremy Mitchell <
> > mitchell852@apache.org
> > >> >
> > >> >> wrote:
> > >> >>
> > >> >>> FYI - I've updated the TO API guidelines to reflect our desire to
> > move
> > >> >> away
> > >> >>> from route/path params and embrace query params in the Golang API.
> > >> >>>
> > >> >>> https://cwiki.apache.org/confluence/display/TC/API+Guidelines
> > >> >>>
> > >> >>> Jeremy
> > >> >>>
> > >> >>
> > >>
> > >>
> >
>

Re: Updated TO API guidelines

Posted by Jeremy Mitchell <mi...@gmail.com>.
Rawlin,

I have submitted a PR to change some new ds request routes to utilize query
params instead of path/route params (the legacy format):

https://github.com/apache/incubator-trafficcontrol/pull/2094

On Fri, Apr 6, 2018 at 11:59 AM, Rawlin Peters <ra...@gmail.com>
wrote:

> Do we currently have an example of an API endpoint written in the
> traffic_ops_golang framework that uses only query parameters like
> this? How would it compare to the legacy format?
>
> -Rawlin
>
> On Thu, Apr 5, 2018 at 9:45 AM, Dewayne Richardson <de...@apache.org>
> wrote:
> > Thank you John for giving us "API Use Cases" to think about with these
> new
> > TO API Guidelines.  The main goal for these changes are to build TO API's
> > that are intuitive.  I'm of the opinion that if the API's are intuitive
> > (with easy to understand patterns) that prevents me from wasting time
> > looking up API docs.  A nice side effect of having simple standards and
> > patterns is that simplicity ripples into our API Go code which allows us
> to
> > easily build frameworks that do all of the work instead of the API
> > snowflakes that we have today.
> >
> > I encourage everyone to shoot as many holes into our thoughts around this
> > new direction so that we can see the bigger picture.
> >
> > -Dew
> >
> > On Wed, Apr 4, 2018 at 10:29 PM, John Rushford <jj...@gmail.com>
> wrote:
> >
> >> Why the change?  It’s my understanding that path parameters should be
> used
> >> to specify a particular resource
> >> and query parameters should be used to sort/filter the query.  Why use a
> >> query parameter to specify a particular
> >> resource?  Is this REST API best practice?
> >>
> >> What about sub resource queries such as using the following:
> >>
> >> GET api/1.3/deliveryservices/{xmlID}/urisigning
> >>
> >> where you are requesting a particular urisigning keys sub resource for
> the
> >> particular deliveryservice resource. You can make it work
> >> with an xmlid query parameter but what do you return if the query
> >> parameter is left off, all uri signing keys?  Is that useful?
> >>
> >> John
> >>
> >> > On Apr 4, 2018, at 3:23 PM, Jeremy Mitchell <mi...@gmail.com>
> >> wrote:
> >> >
> >> > tbh i'm not sure about versioning. I was just trying to suggest that
> new
> >> > routes be formulated this way per the new API guidelines:
> >> >
> >> > GET /foos[?id, name, etc=]
> >> > POST /foos
> >> > PUT /foos [?id, name, etc=]
> >> > DELETE /foos [?id, name, etc=]
> >> >
> >> > instead of the old way:
> >> >
> >> > GET /foos
> >> > GET /foos/:id
> >> > POST /foos
> >> > PUT /foos/:id
> >> > DELETE /foos/:id
> >> >
> >> > The difference being the use of query params over route/path params.
> >> >
> >> > Technically, adding new routes does not break old stuff right so i
> don't
> >> > think that warrants a major version roll.
> >> >
> >> > While we're on the subject, what does everyone think if we took this
> one
> >> > step further and made routes handle a request payload with one or more
> >> > items. For example:
> >> >
> >> > GET /foos[?id, name, etc=]
> >> > POST /foos <-- takes in an array of foos to create
> >> > PUT /foos <-- takes in an array of foos to update
> >> > DELETE /foos <-- takes in an array of foos to delete
> >> >
> >> > in this scenario, query params only pertain to the GET. The POST, PUT
> and
> >> > DELETE rely on the contents of the request json...
> >> >
> >> > Jeremy
> >> >
> >> >
> >> >
> >> >
> >> >
> >> >
> >> >
> >> >
> >> >
> >> >
> >> >
> >> > On Wed, Apr 4, 2018 at 1:55 PM, Robert Butts <
> robert.o.butts@gmail.com>
> >> > wrote:
> >> >
> >> >> That document doesn't mention versions, 1.2 vs 1.3 vs 2.0.
> >> >>
> >> >> Just to clarify, changing to query parameters breaks compatibility
> with
> >> 1.2
> >> >> and older, so new APIs in that format have to be a new major version,
> >> i.e.
> >> >> 2.0, per Semantic Versioning, right?
> >> >>
> >> >> On Tue, Apr 3, 2018 at 3:26 PM, Jeremy Mitchell <
> mitchell852@apache.org
> >> >
> >> >> wrote:
> >> >>
> >> >>> FYI - I've updated the TO API guidelines to reflect our desire to
> move
> >> >> away
> >> >>> from route/path params and embrace query params in the Golang API.
> >> >>>
> >> >>> https://cwiki.apache.org/confluence/display/TC/API+Guidelines
> >> >>>
> >> >>> Jeremy
> >> >>>
> >> >>
> >>
> >>
>

Re: Updated TO API guidelines

Posted by Rawlin Peters <ra...@gmail.com>.
Do we currently have an example of an API endpoint written in the
traffic_ops_golang framework that uses only query parameters like
this? How would it compare to the legacy format?

-Rawlin

On Thu, Apr 5, 2018 at 9:45 AM, Dewayne Richardson <de...@apache.org> wrote:
> Thank you John for giving us "API Use Cases" to think about with these new
> TO API Guidelines.  The main goal for these changes are to build TO API's
> that are intuitive.  I'm of the opinion that if the API's are intuitive
> (with easy to understand patterns) that prevents me from wasting time
> looking up API docs.  A nice side effect of having simple standards and
> patterns is that simplicity ripples into our API Go code which allows us to
> easily build frameworks that do all of the work instead of the API
> snowflakes that we have today.
>
> I encourage everyone to shoot as many holes into our thoughts around this
> new direction so that we can see the bigger picture.
>
> -Dew
>
> On Wed, Apr 4, 2018 at 10:29 PM, John Rushford <jj...@gmail.com> wrote:
>
>> Why the change?  It’s my understanding that path parameters should be used
>> to specify a particular resource
>> and query parameters should be used to sort/filter the query.  Why use a
>> query parameter to specify a particular
>> resource?  Is this REST API best practice?
>>
>> What about sub resource queries such as using the following:
>>
>> GET api/1.3/deliveryservices/{xmlID}/urisigning
>>
>> where you are requesting a particular urisigning keys sub resource for the
>> particular deliveryservice resource. You can make it work
>> with an xmlid query parameter but what do you return if the query
>> parameter is left off, all uri signing keys?  Is that useful?
>>
>> John
>>
>> > On Apr 4, 2018, at 3:23 PM, Jeremy Mitchell <mi...@gmail.com>
>> wrote:
>> >
>> > tbh i'm not sure about versioning. I was just trying to suggest that new
>> > routes be formulated this way per the new API guidelines:
>> >
>> > GET /foos[?id, name, etc=]
>> > POST /foos
>> > PUT /foos [?id, name, etc=]
>> > DELETE /foos [?id, name, etc=]
>> >
>> > instead of the old way:
>> >
>> > GET /foos
>> > GET /foos/:id
>> > POST /foos
>> > PUT /foos/:id
>> > DELETE /foos/:id
>> >
>> > The difference being the use of query params over route/path params.
>> >
>> > Technically, adding new routes does not break old stuff right so i don't
>> > think that warrants a major version roll.
>> >
>> > While we're on the subject, what does everyone think if we took this one
>> > step further and made routes handle a request payload with one or more
>> > items. For example:
>> >
>> > GET /foos[?id, name, etc=]
>> > POST /foos <-- takes in an array of foos to create
>> > PUT /foos <-- takes in an array of foos to update
>> > DELETE /foos <-- takes in an array of foos to delete
>> >
>> > in this scenario, query params only pertain to the GET. The POST, PUT and
>> > DELETE rely on the contents of the request json...
>> >
>> > Jeremy
>> >
>> >
>> >
>> >
>> >
>> >
>> >
>> >
>> >
>> >
>> >
>> > On Wed, Apr 4, 2018 at 1:55 PM, Robert Butts <ro...@gmail.com>
>> > wrote:
>> >
>> >> That document doesn't mention versions, 1.2 vs 1.3 vs 2.0.
>> >>
>> >> Just to clarify, changing to query parameters breaks compatibility with
>> 1.2
>> >> and older, so new APIs in that format have to be a new major version,
>> i.e.
>> >> 2.0, per Semantic Versioning, right?
>> >>
>> >> On Tue, Apr 3, 2018 at 3:26 PM, Jeremy Mitchell <mitchell852@apache.org
>> >
>> >> wrote:
>> >>
>> >>> FYI - I've updated the TO API guidelines to reflect our desire to move
>> >> away
>> >>> from route/path params and embrace query params in the Golang API.
>> >>>
>> >>> https://cwiki.apache.org/confluence/display/TC/API+Guidelines
>> >>>
>> >>> Jeremy
>> >>>
>> >>
>>
>>

Re: Updated TO API guidelines

Posted by Dewayne Richardson <de...@apache.org>.
Thank you John for giving us "API Use Cases" to think about with these new
TO API Guidelines.  The main goal for these changes are to build TO API's
that are intuitive.  I'm of the opinion that if the API's are intuitive
(with easy to understand patterns) that prevents me from wasting time
looking up API docs.  A nice side effect of having simple standards and
patterns is that simplicity ripples into our API Go code which allows us to
easily build frameworks that do all of the work instead of the API
snowflakes that we have today.

I encourage everyone to shoot as many holes into our thoughts around this
new direction so that we can see the bigger picture.

-Dew

On Wed, Apr 4, 2018 at 10:29 PM, John Rushford <jj...@gmail.com> wrote:

> Why the change?  It’s my understanding that path parameters should be used
> to specify a particular resource
> and query parameters should be used to sort/filter the query.  Why use a
> query parameter to specify a particular
> resource?  Is this REST API best practice?
>
> What about sub resource queries such as using the following:
>
> GET api/1.3/deliveryservices/{xmlID}/urisigning
>
> where you are requesting a particular urisigning keys sub resource for the
> particular deliveryservice resource. You can make it work
> with an xmlid query parameter but what do you return if the query
> parameter is left off, all uri signing keys?  Is that useful?
>
> John
>
> > On Apr 4, 2018, at 3:23 PM, Jeremy Mitchell <mi...@gmail.com>
> wrote:
> >
> > tbh i'm not sure about versioning. I was just trying to suggest that new
> > routes be formulated this way per the new API guidelines:
> >
> > GET /foos[?id, name, etc=]
> > POST /foos
> > PUT /foos [?id, name, etc=]
> > DELETE /foos [?id, name, etc=]
> >
> > instead of the old way:
> >
> > GET /foos
> > GET /foos/:id
> > POST /foos
> > PUT /foos/:id
> > DELETE /foos/:id
> >
> > The difference being the use of query params over route/path params.
> >
> > Technically, adding new routes does not break old stuff right so i don't
> > think that warrants a major version roll.
> >
> > While we're on the subject, what does everyone think if we took this one
> > step further and made routes handle a request payload with one or more
> > items. For example:
> >
> > GET /foos[?id, name, etc=]
> > POST /foos <-- takes in an array of foos to create
> > PUT /foos <-- takes in an array of foos to update
> > DELETE /foos <-- takes in an array of foos to delete
> >
> > in this scenario, query params only pertain to the GET. The POST, PUT and
> > DELETE rely on the contents of the request json...
> >
> > Jeremy
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> > On Wed, Apr 4, 2018 at 1:55 PM, Robert Butts <ro...@gmail.com>
> > wrote:
> >
> >> That document doesn't mention versions, 1.2 vs 1.3 vs 2.0.
> >>
> >> Just to clarify, changing to query parameters breaks compatibility with
> 1.2
> >> and older, so new APIs in that format have to be a new major version,
> i.e.
> >> 2.0, per Semantic Versioning, right?
> >>
> >> On Tue, Apr 3, 2018 at 3:26 PM, Jeremy Mitchell <mitchell852@apache.org
> >
> >> wrote:
> >>
> >>> FYI - I've updated the TO API guidelines to reflect our desire to move
> >> away
> >>> from route/path params and embrace query params in the Golang API.
> >>>
> >>> https://cwiki.apache.org/confluence/display/TC/API+Guidelines
> >>>
> >>> Jeremy
> >>>
> >>
>
>

Re: Updated TO API guidelines

Posted by Robert Butts <ro...@apache.org>.
@jjrushford The practical value driving this, is that the Go standard
library's HTTP router can't do path matching. The same is likely true for
any simple language (e.g. C vs Java). Query parameters let us use the
built-in router, saving either a complex bit of routing code, or a large
third party library. They should also be faster, if performance matters.
Most routers use the easier regex matching, which can be slow. Go's
standard router iterates over all routes and does a string comparison on
every one, for every request. Fast methods exist, like a trie, but they're
complex to implement and maintain. While query params are put in a hashmap
passed to the request handler.

In terms of ideology, you're right, the widely-accepted practice is for
path parameters to specify a "resource," and for query params to "filter."
That said, there's nothing in any RFC condoning or requiring that, as far
as I'm aware. (RFC3986 says "The query component contains non-hierarchical
data that, along with data in the path component (Section 3.3), serves to
identify a resource".)

> what do you return if the query parameter is left off
A 4xx, same as if they omitted the path field.

>I know there have been a lot of complaints about having to fetch resources
by id instead of name. This will take care of that.
@mitchell852 +1. Getting rid of IDs in the database and using real data as
keys will be even better, if we can ever get to that point. But that's a
different discussion.

Also to @mitchell852 's point on ambiguity, paths make compound keys
unintuitive, too. For example, is it /api/profile-parameters/foo/bar, or
/api/profile-parameters/bar/foo, or
/api/profile-parameters/profile/foo/parameter/bar,
or /api/profile-parameters/parameter/bar/profile/foo, or
/api/profile/foo/parameter/bar, or /api/parameter/bar/profile/foo, or
/api/profile/foo/bar? You could guess, but there's no unambiguously obvious
right answer, you'd have to look up the docs. Whereas with query params,
/api/profile-parameters?profile=foo&parameter=bar is obvious.

Maybe another way to think about it, for the ideological "resource", is
that the database table (or view) is the resource, and the query params are
filtering that table how you want.

Personally, I'm inclined to put the practical above the ideological in this
case.

But I don't care enough to fight for it. A regex router in Go is 50 lines
of code; it's 50 complex lines, but it's 50 lines. If other people have
strong opinions, I'll step back.


On Thu, Apr 5, 2018 at 8:50 AM, Jeremy Mitchell <mi...@gmail.com>
wrote:

> John,
>
> TBH, it's hard to find any hard and fast rules regarding REST. At least I
> haven't found any.
>
> So the question is why B instead of A:
>
> A. GET api/1.3/deliveryservices/{xmlID}/urisigning
> B. GET api/1.3/deliveryservices_urisigningkeys[?optional queryParams]
>
> I can think of a few reasons:
>
> 1. query params are unambiguous. for example, they look like ?xmlId=foobar.
> there is a key and a value. looking at
> api/1.3/deliveryservices/foobar/urisigning,
> it may not be clear that foobar is the xmlId of the delivery service.
> 2. pattern matching can get screwed up. think of this example. we have 2
> routes defined:
>
> GET /foos/:id
> GET /foos/:name
>
> which route does this match? GET /foos/42
>
> maybe names can be numbers. so is 42 an ID or a Name? not sure.
>
> 3. we can get away with less route definitions. instead of 3 routes:
>
> GET /foos <-- get all foos
> GET /foos/:id <-- get foo by id
> GET /foos/:name <-- get foo by name
>
> we can simply have 1:
>
> GET /foos with optional query params (?id= or ?name=)
>
> I know there have been a lot of complaints about having to fetch resources
> by id instead of name. This will take care of that.
>
> 4. Nested routes can start to get a little nasty and uneccessary imo. GET
> /foos/:id/bars/:id/comments/:id (there can be a lot of permutations of
> that) where you really only need the id of the comment to retrieve it: GET
> /foo_bar_comments?id=4
>
> 5. There are some built in benefits in Go but I'll have to defer to Rob
> and/or Dylan regarding that.
>
> Off the top of my head, that's all i can think of. If we plan to use tools
> such as Swagger for our API, we need to agree on a standard for the API and
> stick to it. We're simply trying to find that standard. :)
>
> Jeremy
>
>
>
>
>
> On Wed, Apr 4, 2018 at 10:29 PM, John Rushford <jj...@gmail.com>
> wrote:
>
> > Why the change?  It’s my understanding that path parameters should be
> used
> > to specify a particular resource
> > and query parameters should be used to sort/filter the query.  Why use a
> > query parameter to specify a particular
> > resource?  Is this REST API best practice?
> >
> > What about sub resource queries such as using the following:
> >
> > GET api/1.3/deliveryservices/{xmlID}/urisigning
> >
> > where you are requesting a particular urisigning keys sub resource for
> the
> > particular deliveryservice resource. You can make it work
> > with an xmlid query parameter but what do you return if the query
> > parameter is left off, all uri signing keys?  Is that useful?
> >
> > John
> >
> > > On Apr 4, 2018, at 3:23 PM, Jeremy Mitchell <mi...@gmail.com>
> > wrote:
> > >
> > > tbh i'm not sure about versioning. I was just trying to suggest that
> new
> > > routes be formulated this way per the new API guidelines:
> > >
> > > GET /foos[?id, name, etc=]
> > > POST /foos
> > > PUT /foos [?id, name, etc=]
> > > DELETE /foos [?id, name, etc=]
> > >
> > > instead of the old way:
> > >
> > > GET /foos
> > > GET /foos/:id
> > > POST /foos
> > > PUT /foos/:id
> > > DELETE /foos/:id
> > >
> > > The difference being the use of query params over route/path params.
> > >
> > > Technically, adding new routes does not break old stuff right so i
> don't
> > > think that warrants a major version roll.
> > >
> > > While we're on the subject, what does everyone think if we took this
> one
> > > step further and made routes handle a request payload with one or more
> > > items. For example:
> > >
> > > GET /foos[?id, name, etc=]
> > > POST /foos <-- takes in an array of foos to create
> > > PUT /foos <-- takes in an array of foos to update
> > > DELETE /foos <-- takes in an array of foos to delete
> > >
> > > in this scenario, query params only pertain to the GET. The POST, PUT
> and
> > > DELETE rely on the contents of the request json...
> > >
> > > Jeremy
> > >
> > >
> > >
> > >
> > >
> > >
> > >
> > >
> > >
> > >
> > >
> > > On Wed, Apr 4, 2018 at 1:55 PM, Robert Butts <robert.o.butts@gmail.com
> >
> > > wrote:
> > >
> > >> That document doesn't mention versions, 1.2 vs 1.3 vs 2.0.
> > >>
> > >> Just to clarify, changing to query parameters breaks compatibility
> with
> > 1.2
> > >> and older, so new APIs in that format have to be a new major version,
> > i.e.
> > >> 2.0, per Semantic Versioning, right?
> > >>
> > >> On Tue, Apr 3, 2018 at 3:26 PM, Jeremy Mitchell <
> mitchell852@apache.org
> > >
> > >> wrote:
> > >>
> > >>> FYI - I've updated the TO API guidelines to reflect our desire to
> move
> > >> away
> > >>> from route/path params and embrace query params in the Golang API.
> > >>>
> > >>> https://cwiki.apache.org/confluence/display/TC/API+Guidelines
> > >>>
> > >>> Jeremy
> > >>>
> > >>
> >
> >
>

Re: Updated TO API guidelines

Posted by Jeremy Mitchell <mi...@gmail.com>.
John,

TBH, it's hard to find any hard and fast rules regarding REST. At least I
haven't found any.

So the question is why B instead of A:

A. GET api/1.3/deliveryservices/{xmlID}/urisigning
B. GET api/1.3/deliveryservices_urisigningkeys[?optional queryParams]

I can think of a few reasons:

1. query params are unambiguous. for example, they look like ?xmlId=foobar.
there is a key and a value. looking at
api/1.3/deliveryservices/foobar/urisigning,
it may not be clear that foobar is the xmlId of the delivery service.
2. pattern matching can get screwed up. think of this example. we have 2
routes defined:

GET /foos/:id
GET /foos/:name

which route does this match? GET /foos/42

maybe names can be numbers. so is 42 an ID or a Name? not sure.

3. we can get away with less route definitions. instead of 3 routes:

GET /foos <-- get all foos
GET /foos/:id <-- get foo by id
GET /foos/:name <-- get foo by name

we can simply have 1:

GET /foos with optional query params (?id= or ?name=)

I know there have been a lot of complaints about having to fetch resources
by id instead of name. This will take care of that.

4. Nested routes can start to get a little nasty and uneccessary imo. GET
/foos/:id/bars/:id/comments/:id (there can be a lot of permutations of
that) where you really only need the id of the comment to retrieve it: GET
/foo_bar_comments?id=4

5. There are some built in benefits in Go but I'll have to defer to Rob
and/or Dylan regarding that.

Off the top of my head, that's all i can think of. If we plan to use tools
such as Swagger for our API, we need to agree on a standard for the API and
stick to it. We're simply trying to find that standard. :)

Jeremy





On Wed, Apr 4, 2018 at 10:29 PM, John Rushford <jj...@gmail.com> wrote:

> Why the change?  It’s my understanding that path parameters should be used
> to specify a particular resource
> and query parameters should be used to sort/filter the query.  Why use a
> query parameter to specify a particular
> resource?  Is this REST API best practice?
>
> What about sub resource queries such as using the following:
>
> GET api/1.3/deliveryservices/{xmlID}/urisigning
>
> where you are requesting a particular urisigning keys sub resource for the
> particular deliveryservice resource. You can make it work
> with an xmlid query parameter but what do you return if the query
> parameter is left off, all uri signing keys?  Is that useful?
>
> John
>
> > On Apr 4, 2018, at 3:23 PM, Jeremy Mitchell <mi...@gmail.com>
> wrote:
> >
> > tbh i'm not sure about versioning. I was just trying to suggest that new
> > routes be formulated this way per the new API guidelines:
> >
> > GET /foos[?id, name, etc=]
> > POST /foos
> > PUT /foos [?id, name, etc=]
> > DELETE /foos [?id, name, etc=]
> >
> > instead of the old way:
> >
> > GET /foos
> > GET /foos/:id
> > POST /foos
> > PUT /foos/:id
> > DELETE /foos/:id
> >
> > The difference being the use of query params over route/path params.
> >
> > Technically, adding new routes does not break old stuff right so i don't
> > think that warrants a major version roll.
> >
> > While we're on the subject, what does everyone think if we took this one
> > step further and made routes handle a request payload with one or more
> > items. For example:
> >
> > GET /foos[?id, name, etc=]
> > POST /foos <-- takes in an array of foos to create
> > PUT /foos <-- takes in an array of foos to update
> > DELETE /foos <-- takes in an array of foos to delete
> >
> > in this scenario, query params only pertain to the GET. The POST, PUT and
> > DELETE rely on the contents of the request json...
> >
> > Jeremy
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> > On Wed, Apr 4, 2018 at 1:55 PM, Robert Butts <ro...@gmail.com>
> > wrote:
> >
> >> That document doesn't mention versions, 1.2 vs 1.3 vs 2.0.
> >>
> >> Just to clarify, changing to query parameters breaks compatibility with
> 1.2
> >> and older, so new APIs in that format have to be a new major version,
> i.e.
> >> 2.0, per Semantic Versioning, right?
> >>
> >> On Tue, Apr 3, 2018 at 3:26 PM, Jeremy Mitchell <mitchell852@apache.org
> >
> >> wrote:
> >>
> >>> FYI - I've updated the TO API guidelines to reflect our desire to move
> >> away
> >>> from route/path params and embrace query params in the Golang API.
> >>>
> >>> https://cwiki.apache.org/confluence/display/TC/API+Guidelines
> >>>
> >>> Jeremy
> >>>
> >>
>
>

Re: Updated TO API guidelines

Posted by John Rushford <jj...@gmail.com>.
Why the change?  It’s my understanding that path parameters should be used to specify a particular resource
and query parameters should be used to sort/filter the query.  Why use a query parameter to specify a particular
resource?  Is this REST API best practice?

What about sub resource queries such as using the following:

GET api/1.3/deliveryservices/{xmlID}/urisigning

where you are requesting a particular urisigning keys sub resource for the particular deliveryservice resource. You can make it work
with an xmlid query parameter but what do you return if the query parameter is left off, all uri signing keys?  Is that useful?

John

> On Apr 4, 2018, at 3:23 PM, Jeremy Mitchell <mi...@gmail.com> wrote:
> 
> tbh i'm not sure about versioning. I was just trying to suggest that new
> routes be formulated this way per the new API guidelines:
> 
> GET /foos[?id, name, etc=]
> POST /foos
> PUT /foos [?id, name, etc=]
> DELETE /foos [?id, name, etc=]
> 
> instead of the old way:
> 
> GET /foos
> GET /foos/:id
> POST /foos
> PUT /foos/:id
> DELETE /foos/:id
> 
> The difference being the use of query params over route/path params.
> 
> Technically, adding new routes does not break old stuff right so i don't
> think that warrants a major version roll.
> 
> While we're on the subject, what does everyone think if we took this one
> step further and made routes handle a request payload with one or more
> items. For example:
> 
> GET /foos[?id, name, etc=]
> POST /foos <-- takes in an array of foos to create
> PUT /foos <-- takes in an array of foos to update
> DELETE /foos <-- takes in an array of foos to delete
> 
> in this scenario, query params only pertain to the GET. The POST, PUT and
> DELETE rely on the contents of the request json...
> 
> Jeremy
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> On Wed, Apr 4, 2018 at 1:55 PM, Robert Butts <ro...@gmail.com>
> wrote:
> 
>> That document doesn't mention versions, 1.2 vs 1.3 vs 2.0.
>> 
>> Just to clarify, changing to query parameters breaks compatibility with 1.2
>> and older, so new APIs in that format have to be a new major version, i.e.
>> 2.0, per Semantic Versioning, right?
>> 
>> On Tue, Apr 3, 2018 at 3:26 PM, Jeremy Mitchell <mi...@apache.org>
>> wrote:
>> 
>>> FYI - I've updated the TO API guidelines to reflect our desire to move
>> away
>>> from route/path params and embrace query params in the Golang API.
>>> 
>>> https://cwiki.apache.org/confluence/display/TC/API+Guidelines
>>> 
>>> Jeremy
>>> 
>> 


Re: Updated TO API guidelines

Posted by Jeremy Mitchell <mi...@gmail.com>.
tbh i'm not sure about versioning. I was just trying to suggest that new
routes be formulated this way per the new API guidelines:

GET /foos[?id, name, etc=]
POST /foos
PUT /foos [?id, name, etc=]
DELETE /foos [?id, name, etc=]

instead of the old way:

GET /foos
GET /foos/:id
POST /foos
PUT /foos/:id
DELETE /foos/:id

The difference being the use of query params over route/path params.

Technically, adding new routes does not break old stuff right so i don't
think that warrants a major version roll.

While we're on the subject, what does everyone think if we took this one
step further and made routes handle a request payload with one or more
items. For example:

GET /foos[?id, name, etc=]
POST /foos <-- takes in an array of foos to create
PUT /foos <-- takes in an array of foos to update
DELETE /foos <-- takes in an array of foos to delete

in this scenario, query params only pertain to the GET. The POST, PUT and
DELETE rely on the contents of the request json...

Jeremy











On Wed, Apr 4, 2018 at 1:55 PM, Robert Butts <ro...@gmail.com>
wrote:

> That document doesn't mention versions, 1.2 vs 1.3 vs 2.0.
>
> Just to clarify, changing to query parameters breaks compatibility with 1.2
> and older, so new APIs in that format have to be a new major version, i.e.
> 2.0, per Semantic Versioning, right?
>
> On Tue, Apr 3, 2018 at 3:26 PM, Jeremy Mitchell <mi...@apache.org>
> wrote:
>
> > FYI - I've updated the TO API guidelines to reflect our desire to move
> away
> > from route/path params and embrace query params in the Golang API.
> >
> > https://cwiki.apache.org/confluence/display/TC/API+Guidelines
> >
> > Jeremy
> >
>

Re: Updated TO API guidelines

Posted by Robert Butts <ro...@gmail.com>.
That document doesn't mention versions, 1.2 vs 1.3 vs 2.0.

Just to clarify, changing to query parameters breaks compatibility with 1.2
and older, so new APIs in that format have to be a new major version, i.e.
2.0, per Semantic Versioning, right?

On Tue, Apr 3, 2018 at 3:26 PM, Jeremy Mitchell <mi...@apache.org>
wrote:

> FYI - I've updated the TO API guidelines to reflect our desire to move away
> from route/path params and embrace query params in the Golang API.
>
> https://cwiki.apache.org/confluence/display/TC/API+Guidelines
>
> Jeremy
>