Example of Foreman V2 API controller and functional test

Adam,

To see an example of Foreman API v2, you can view the branch https://github.com/isratrade/foreman/tree/3491_v2

Note that this is not merged yet in Foreman 'develop' branch.

I'm using architectures as a basic CRUD example. Go to /api/architectures (with version=2 in header) and you should see something like this

{
"total": 4,
"subtotal": 4,
"page": 1,
"per_page": 20,
"search": null,
"sort": {
"by": null,
"order": null
},
"results": [
{
"name": "i386",
"id": 2,
"created_at": "2010-08-15T10:15:27Z",
"updated_at": "2010-08-15T10:15:27Z"
},
{
"name": "Sparc",
"id": 3,
"created_at": "2012-01-02T15:42:28Z",
"updated_at": "2012-01-02T15:42:28Z"
},
{
"name": "armv5tel",
"id": 8,
"created_at": "2012-07-16T09:19:16Z",
"updated_at": "2012-07-16T09:19:16Z"
},
{
"name": "x86_64",
"id": 1,
"created_at": "2010-08-15T10:15:27Z",
"updated_at": "2013-09-03T14:34:45Z"
}
]
}

If you go to /api/architectures/2, you should see

{
"architecture": {
"name": "i386",
"id": 2,
"created_at": "2010-08-15T10:15:27Z",
"updated_at": "2010-08-15T10:15:27Z"
}
}

Note: TBD is the root_name will go away or it will be called something else.

Architecture has 3 has_many relationships, so we plan to add the following 3 nested routes, but this is not ready yet

api/architectures/:id/hostgroups
api/architectures/:id/images
api/architectures/:id/operatingsystems

Also, we may include none, one or all of the relationship data in the 'show' response. It's dependent on each object.

I used a RABL layout to show the metadata on each :index action. See https://github.com/isratrade/foreman/blob/3491_v2/app/views/api/v2/layouts/index_layout.json.erb

{
"total": <%= @total.to_json %>,
"subtotal": <%= @subtotal.to_json %>,
"page": <%= @page.to_json %>,
"per_page": <%= @per_page.to_json %>,
"search": <%= @search.to_json.html_safe %>,
"sort": {
"by": <%= @by.to_json.html_safe %>,
"order": <%= @order.to_json.html_safe %>
},
"<%= "#{@root_node_name}" %>": <%= yield %>
}

In Api:V2::BaseController, I have two callbacks to get the instance variables for the layout above.
Note, that I added the gem 'rails3_before_render' to get the method before_render.

  before_filter :root_node_name, :only =&gt; :index
  before_render :get_metadata, :only =&gt; :index
  layout &#39;api/v2/layouts/index_layout&#39;, :only =&gt; :index

The Rabl templates for architectures are found at https://github.com/isratrade/foreman/tree/3491_v2/app/views/api/v2/architectures

If interested, there is also a Rabl initializer at https://github.com/isratrade/foreman/blob/3491_v2/config/initializers/rabl_init.rb
that was needed for v2, since we couldn't change the global Rabl default settings. If we did, it would break v1.

Basic functional tests for the api v2 architecture controller is at https://github.com/isratrade/foreman/blob/3491_v2/test/functional/api/v2/architectures_controller_test.rb

I tested the metadata response only in one controller (locations) that you can see at https://github.com/isratrade/foreman/blob/3491_v2/test/functional/api/v2/locations_controller_test.rb#L86

I hope that helps. Let me know if you have any questions.

Regards,

Joseph

Thanks for putting all this together?

One question on this:

Architecture has 3 has_many relationships, so we plan to add the following
3 nested routes, but this is not ready yet

api/architectures/:id/hostgroups
api/architectures/:id/images
api/architectures/:id/operatingsystems

Do you think this is reasonable for nested routes:

  api_resources :activation_keys, :only =&gt; [:show, :destroy, :create, 

:index, :update] do
member do
match '/subscriptions/available' =>
'activation_keys#available_subscriptions', :via => :get
match '/subscriptions/:subscription_id' =>
'activation_keys#show_subscription', :via => :get
match '/subscriptions' =>
'activation_keys#index_subscriptions', :via => :get
match '/subscriptions' =>
'activation_keys#create_subscription', :via => :post
match '/subscriptions/:subscription_id' =>
'activation_keys#update_subscription', :via => :put
match '/subscriptions/:subscription_id' =>
'activation_keys#remove_subscription', :via => :delete

Also, what is the format of results to a call to GET
/activation_keys/2/subscriptions? Is it the same format as /subscriptions
with data specific to act key 2 context?

··· On Monday, October 28, 2013 6:17:45 PM UTC-4, Joseph Magen wrote: > > Adam, > > To see an example of Foreman API v2, you can view the branch > https://github.com/isratrade/foreman/tree/3491_v2 > > Note that this is not merged yet in Foreman 'develop' branch. > > I'm using architectures as a basic CRUD example. Go to /api/architectures > (with version=2 in header) and you should see something like this > > { > "total": 4, > "subtotal": 4, > "page": 1, > "per_page": 20, > "search": null, > "sort": { > "by": null, > "order": null > }, > "results": [ > { > "name": "i386", > "id": 2, > "created_at": "2010-08-15T10:15:27Z", > "updated_at": "2010-08-15T10:15:27Z" > }, > { > "name": "Sparc", > "id": 3, > "created_at": "2012-01-02T15:42:28Z", > "updated_at": "2012-01-02T15:42:28Z" > }, > { > "name": "armv5tel", > "id": 8, > "created_at": "2012-07-16T09:19:16Z", > "updated_at": "2012-07-16T09:19:16Z" > }, > { > "name": "x86_64", > "id": 1, > "created_at": "2010-08-15T10:15:27Z", > "updated_at": "2013-09-03T14:34:45Z" > } > ] > } > > > If you go to /api/architectures/2, you should see > > > { > "architecture": { > "name": "i386", > "id": 2, > "created_at": "2010-08-15T10:15:27Z", > "updated_at": "2010-08-15T10:15:27Z" > } > } > > Note: TBD is the root_name will go away or it will be called something > else. > > Architecture has 3 has_many relationships, so we plan to add the following > 3 nested routes, but this is not ready yet > > api/architectures/:id/hostgroups > api/architectures/:id/images > api/architectures/:id/operatingsystems > > Also, we may include none, one or all of the relationship data in the > 'show' response. It's dependent on each object. > > I used a RABL layout to show the metadata on each :index action. See > https://github.com/isratrade/foreman/blob/3491_v2/app/views/api/v2/layouts/index_layout.json.erb > > { > "total": <%= @total.to_json %>, > "subtotal": <%= @subtotal.to_json %>, > "page": <%= @page.to_json %>, > "per_page": <%= @per_page.to_json %>, > "search": <%= @search.to_json.html_safe %>, > "sort": { > "by": <%= @by.to_json.html_safe %>, > "order": <%= @order.to_json.html_safe %> > }, > "<%= "#{@root_node_name}" %>": <%= yield %> > } > > In Api:V2::BaseController, I have two callbacks to get the instance > variables for the layout above. > Note, that I added the gem 'rails3_before_render' to get the method > before_render. > > https://github.com/isratrade/foreman/blob/3491_v2/app/controllers/api/v2/base_controller.rb > > before_filter :root_node_name, :only => :index > before_render :get_metadata, :only => :index > layout 'api/v2/layouts/index_layout', :only => :index > > The Rabl templates for architectures are found at > https://github.com/isratrade/foreman/tree/3491_v2/app/views/api/v2/architectures > > If interested, there is also a Rabl initializer at > https://github.com/isratrade/foreman/blob/3491_v2/config/initializers/rabl_init.rb > that was needed for v2, since we couldn't change the global Rabl default > settings. If we did, it would break v1. > > Basic functional tests for the api v2 architecture controller is at > https://github.com/isratrade/foreman/blob/3491_v2/test/functional/api/v2/architectures_controller_test.rb > > I tested the metadata response only in one controller (locations) that you > can see at > https://github.com/isratrade/foreman/blob/3491_v2/test/functional/api/v2/locations_controller_test.rb#L86 > > I hope that helps. Let me know if you have any questions. > > Regards, > > Joseph > > > > > > >

Tom,

For the routes, I would do this

resources :activation_keys, :only => [:show, :destroy, :create, :index, :update] do
resources :subscriptions, :only => [:available, :show, :index, :create, :update, :destroy]
end

You don't need to use a 'member do' loop and then explicitly match each wrote to controller for RESTful resources. Nested resources does this for you.

Also, what does method api_resources do that method resources does not? It's it just adding /api/, I feel it's better to wrap all the routes with 'namespace :api do'

Regards,

Joseph

··· > member do > match '/subscriptions/available' => > 'activation_keys#available_subscriptions', :via => :get > match '/subscriptions/:subscription_id' => > 'activation_keys#show_subscription', :via => :get > match '/subscriptions' => > 'activation_keys#index_subscriptions', :via => :get > match '/subscriptions' => > 'activation_keys#create_subscription', :via => :post > match '/subscriptions/:subscription_id' => > 'activation_keys#update_subscription', :via => :put > match '/subscriptions/:subscription_id' => > 'activation_keys#remove_subscription', :via => :delete

----- Original Message -----

From: “Thomas McKay” thomasfmckay@gmail.com
To: foreman-dev@googlegroups.com
Cc: “Adam Price” adprice@redhat.com
Sent: Tuesday, October 29, 2013 12:51:38 AM
Subject: [foreman-dev] Re: example of Foreman V2 API controller and functional test

Thanks for putting all this together?

One question on this:

Architecture has 3 has_many relationships, so we plan to add the following
3 nested routes, but this is not ready yet

api/architectures/:id/hostgroups
api/architectures/:id/images
api/architectures/:id/operatingsystems

Do you think this is reasonable for nested routes:

  api_resources :activation_keys, :only => [:show, :destroy, :create,

:index, :update] do
member do
match ‘/subscriptions/available’ =>
‘activation_keys#available_subscriptions’, :via => :get
match ‘/subscriptions/:subscription_id’ =>
‘activation_keys#show_subscription’, :via => :get
match ‘/subscriptions’ =>
‘activation_keys#index_subscriptions’, :via => :get
match ‘/subscriptions’ =>
‘activation_keys#create_subscription’, :via => :post
match ‘/subscriptions/:subscription_id’ =>
‘activation_keys#update_subscription’, :via => :put
match ‘/subscriptions/:subscription_id’ =>
‘activation_keys#remove_subscription’, :via => :delete

Also, what is the format of results to a call to GET
/activation_keys/2/subscriptions? Is it the same format as /subscriptions
with data specific to act key 2 context?

On Monday, October 28, 2013 6:17:45 PM UTC-4, Joseph Magen wrote:

Adam,

To see an example of Foreman API v2, you can view the branch
https://github.com/isratrade/foreman/tree/3491_v2

Note that this is not merged yet in Foreman ‘develop’ branch.

I’m using architectures as a basic CRUD example. Go to /api/architectures
(with version=2 in header) and you should see something like this

{
“total”: 4,
“subtotal”: 4,
“page”: 1,
“per_page”: 20,
“search”: null,
“sort”: {
“by”: null,
“order”: null
},
“results”: [
{
“name”: “i386”,
“id”: 2,
“created_at”: “2010-08-15T10:15:27Z”,
“updated_at”: “2010-08-15T10:15:27Z”
},
{
“name”: “Sparc”,
“id”: 3,
“created_at”: “2012-01-02T15:42:28Z”,
“updated_at”: “2012-01-02T15:42:28Z”
},
{
“name”: “armv5tel”,
“id”: 8,
“created_at”: “2012-07-16T09:19:16Z”,
“updated_at”: “2012-07-16T09:19:16Z”
},
{
“name”: “x86_64”,
“id”: 1,
“created_at”: “2010-08-15T10:15:27Z”,
“updated_at”: “2013-09-03T14:34:45Z”
}
]
}

If you go to /api/architectures/2, you should see

{
“architecture”: {
“name”: “i386”,
“id”: 2,
“created_at”: “2010-08-15T10:15:27Z”,
“updated_at”: “2010-08-15T10:15:27Z”
}
}

Note: TBD is the root_name will go away or it will be called something
else.

Architecture has 3 has_many relationships, so we plan to add the following
3 nested routes, but this is not ready yet

api/architectures/:id/hostgroups
api/architectures/:id/images
api/architectures/:id/operatingsystems

Also, we may include none, one or all of the relationship data in the
’show’ response. It’s dependent on each object.

I used a RABL layout to show the metadata on each :index action. See
https://github.com/isratrade/foreman/blob/3491_v2/app/views/api/v2/layouts/index_layout.json.erb

{
“total”: <%= @total.to_json %>,
“subtotal”: <%= @subtotal.to_json %>,
“page”: <%= @page.to_json %>,
“per_page”: <%= @per_page.to_json %>,
“search”: <%= @search.to_json.html_safe %>,
“sort”: {
“by”: <%= @by.to_json.html_safe %>,
“order”: <%= @order.to_json.html_safe %>
},
"<%= “#{@root_node_name}” %>": <%= yield %>
}

In Api:V2::BaseController, I have two callbacks to get the instance
variables for the layout above.
Note, that I added the gem ‘rails3_before_render’ to get the method
before_render.

https://github.com/isratrade/foreman/blob/3491_v2/app/controllers/api/v2/base_controller.rb

  before_filter :root_node_name, :only => :index
  before_render :get_metadata, :only => :index
  layout 'api/v2/layouts/index_layout', :only => :index

The Rabl templates for architectures are found at
https://github.com/isratrade/foreman/tree/3491_v2/app/views/api/v2/architectures

If interested, there is also a Rabl initializer at
https://github.com/isratrade/foreman/blob/3491_v2/config/initializers/rabl_init.rb
that was needed for v2, since we couldn’t change the global Rabl default
settings. If we did, it would break v1.

Basic functional tests for the api v2 architecture controller is at
https://github.com/isratrade/foreman/blob/3491_v2/test/functional/api/v2/architectures_controller_test.rb

I tested the metadata response only in one controller (locations) that you
can see at
https://github.com/isratrade/foreman/blob/3491_v2/test/functional/api/v2/locations_controller_test.rb#L86

I hope that helps. Let me know if you have any questions.

Regards,

Joseph


You received this message because you are subscribed to the Google Groups
"foreman-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an
email to foreman-dev+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

> Also, what is the format of results to a call to GET
> /activation_keys/2/subscriptions? Is it the same format as /subscriptions
> with data specific to act key 2 context?

yes, same format.

··· ----- Original Message ----- > From: "Joseph Magen" > To: foreman-dev@googlegroups.com > Cc: "Adam Price" > Sent: Tuesday, October 29, 2013 9:54:15 AM > Subject: Re: [foreman-dev] Re: example of Foreman V2 API controller and functional test > > Tom, > > For the routes, I would do this > > resources :activation_keys, :only => [:show, :destroy, :create, :index, > :update] do > resources :subscriptions, :only => [:available, :show, :index, :create, > :update, :destroy] > end > > You don't need to use a 'member do' loop and then explicitly match each wrote > to controller for RESTful resources. Nested resources does this for you. > > Also, what does method api_resources do that method resources does not? It's > it just adding /api/, I feel it's better to wrap all the routes with > 'namespace :api do' > > Regards, > > Joseph > > > > > member do > > match '/subscriptions/available' => > > 'activation_keys#available_subscriptions', :via => :get > > match '/subscriptions/:subscription_id' => > > 'activation_keys#show_subscription', :via => :get > > match '/subscriptions' => > > 'activation_keys#index_subscriptions', :via => :get > > match '/subscriptions' => > > 'activation_keys#create_subscription', :via => :post > > match '/subscriptions/:subscription_id' => > > 'activation_keys#update_subscription', :via => :put > > match '/subscriptions/:subscription_id' => > > 'activation_keys#remove_subscription', :via => :delete > > > > ----- Original Message ----- > > From: "Thomas McKay" > > To: foreman-dev@googlegroups.com > > Cc: "Adam Price" > > Sent: Tuesday, October 29, 2013 12:51:38 AM > > Subject: [foreman-dev] Re: example of Foreman V2 API controller and > > functional test > > > > Thanks for putting all this together? > > > > One question on this: > > > > Architecture has 3 has_many relationships, so we plan to add the following > > 3 nested routes, but this is not ready yet > > > > api/architectures/:id/hostgroups > > api/architectures/:id/images > > api/architectures/:id/operatingsystems > > > > > > Do you think this is reasonable for nested routes: > > > > api_resources :activation_keys, :only => [:show, :destroy, :create, > > :index, :update] do > > member do > > match '/subscriptions/available' => > > 'activation_keys#available_subscriptions', :via => :get > > match '/subscriptions/:subscription_id' => > > 'activation_keys#show_subscription', :via => :get > > match '/subscriptions' => > > 'activation_keys#index_subscriptions', :via => :get > > match '/subscriptions' => > > 'activation_keys#create_subscription', :via => :post > > match '/subscriptions/:subscription_id' => > > 'activation_keys#update_subscription', :via => :put > > match '/subscriptions/:subscription_id' => > > 'activation_keys#remove_subscription', :via => :delete > > > > Also, what is the format of results to a call to GET > > /activation_keys/2/subscriptions? Is it the same format as /subscriptions > > with data specific to act key 2 context? > > > > > > > > On Monday, October 28, 2013 6:17:45 PM UTC-4, Joseph Magen wrote: > > > > > > Adam, > > > > > > To see an example of Foreman API v2, you can view the branch > > > https://github.com/isratrade/foreman/tree/3491_v2 > > > > > > Note that this is not merged yet in Foreman 'develop' branch. > > > > > > I'm using architectures as a basic CRUD example. Go to > > > /api/architectures > > > (with version=2 in header) and you should see something like this > > > > > > { > > > "total": 4, > > > "subtotal": 4, > > > "page": 1, > > > "per_page": 20, > > > "search": null, > > > "sort": { > > > "by": null, > > > "order": null > > > }, > > > "results": [ > > > { > > > "name": "i386", > > > "id": 2, > > > "created_at": "2010-08-15T10:15:27Z", > > > "updated_at": "2010-08-15T10:15:27Z" > > > }, > > > { > > > "name": "Sparc", > > > "id": 3, > > > "created_at": "2012-01-02T15:42:28Z", > > > "updated_at": "2012-01-02T15:42:28Z" > > > }, > > > { > > > "name": "armv5tel", > > > "id": 8, > > > "created_at": "2012-07-16T09:19:16Z", > > > "updated_at": "2012-07-16T09:19:16Z" > > > }, > > > { > > > "name": "x86_64", > > > "id": 1, > > > "created_at": "2010-08-15T10:15:27Z", > > > "updated_at": "2013-09-03T14:34:45Z" > > > } > > > ] > > > } > > > > > > > > > If you go to /api/architectures/2, you should see > > > > > > > > > { > > > "architecture": { > > > "name": "i386", > > > "id": 2, > > > "created_at": "2010-08-15T10:15:27Z", > > > "updated_at": "2010-08-15T10:15:27Z" > > > } > > > } > > > > > > Note: TBD is the root_name will go away or it will be called something > > > else. > > > > > > Architecture has 3 has_many relationships, so we plan to add the > > > following > > > 3 nested routes, but this is not ready yet > > > > > > api/architectures/:id/hostgroups > > > api/architectures/:id/images > > > api/architectures/:id/operatingsystems > > > > > > Also, we may include none, one or all of the relationship data in the > > > 'show' response. It's dependent on each object. > > > > > > I used a RABL layout to show the metadata on each :index action. See > > > https://github.com/isratrade/foreman/blob/3491_v2/app/views/api/v2/layouts/index_layout.json.erb > > > > > > { > > > "total": <%= @total.to_json %>, > > > "subtotal": <%= @subtotal.to_json %>, > > > "page": <%= @page.to_json %>, > > > "per_page": <%= @per_page.to_json %>, > > > "search": <%= @search.to_json.html_safe %>, > > > "sort": { > > > "by": <%= @by.to_json.html_safe %>, > > > "order": <%= @order.to_json.html_safe %> > > > }, > > > "<%= "#{@root_node_name}" %>": <%= yield %> > > > } > > > > > > In Api:V2::BaseController, I have two callbacks to get the instance > > > variables for the layout above. > > > Note, that I added the gem 'rails3_before_render' to get the method > > > before_render. > > > > > > https://github.com/isratrade/foreman/blob/3491_v2/app/controllers/api/v2/base_controller.rb > > > > > > before_filter :root_node_name, :only => :index > > > before_render :get_metadata, :only => :index > > > layout 'api/v2/layouts/index_layout', :only => :index > > > > > > The Rabl templates for architectures are found at > > > https://github.com/isratrade/foreman/tree/3491_v2/app/views/api/v2/architectures > > > > > > If interested, there is also a Rabl initializer at > > > https://github.com/isratrade/foreman/blob/3491_v2/config/initializers/rabl_init.rb > > > that was needed for v2, since we couldn't change the global Rabl default > > > settings. If we did, it would break v1. > > > > > > Basic functional tests for the api v2 architecture controller is at > > > https://github.com/isratrade/foreman/blob/3491_v2/test/functional/api/v2/architectures_controller_test.rb > > > > > > I tested the metadata response only in one controller (locations) that > > > you > > > can see at > > > https://github.com/isratrade/foreman/blob/3491_v2/test/functional/api/v2/locations_controller_test.rb#L86 > > > > > > I hope that helps. Let me know if you have any questions. > > > > > > Regards, > > > > > > Joseph > > > > > > > > > > > > > > > > > > > > > > > > > -- > > You received this message because you are subscribed to the Google Groups > > "foreman-dev" group. > > To unsubscribe from this group and stop receiving emails from it, send an > > email to foreman-dev+unsubscribe@googlegroups.com. > > For more options, visit https://groups.google.com/groups/opt_out. > > > > -- > You received this message because you are subscribed to the Google Groups > "foreman-dev" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to foreman-dev+unsubscribe@googlegroups.com. > For more options, visit https://groups.google.com/groups/opt_out. >

>
> > Also, what is the format of results to a call to GET
> > /activation_keys/2/subscriptions? Is it the same format as
> /subscriptions
> > with data specific to act key 2 context?
>
> yes, same format.
>
>
Taking subscriptions on activation key as an example, there is a quantity
with the association, how is that represented?

POST /activation_keys/2/subscriptions {subscription_id: 3, quantity: 1}
–> { ??? }

GET /activation-keys/2/subscriptions
–> { ??? }

GET /activation-keys/2/subscriptions/3
–> { ??? }

GET /activation-keys/2
–> { id:2, subscriptions:[{id:3, quantity:1, name:"RHEL 6.4"}]}

It's this sort of example that I'd like to see make it into the docs before
the katello devs begin updating the v2 controllers and making hammer cli.

Thanks!

··· On Tuesday, October 29, 2013 4:19:58 AM UTC-4, Joseph Magen wrote:

----- Original Message -----

From: “Joseph Magen” <jma...@redhat.com <javascript:>>
To: forem...@googlegroups.com <javascript:>
Cc: “Adam Price” <adp...@redhat.com <javascript:>>
Sent: Tuesday, October 29, 2013 9:54:15 AM
Subject: Re: [foreman-dev] Re: example of Foreman V2 API controller and
functional test

Tom,

For the routes, I would do this

resources :activation_keys, :only => [:show, :destroy, :create, :index,
:update] do
resources :subscriptions, :only => [:available, :show, :index,
:create,
:update, :destroy]
end

You don’t need to use a ‘member do’ loop and then explicitly match each
wrote
to controller for RESTful resources. Nested resources does this for
you.

Also, what does method api_resources do that method resources does not?
It’s
it just adding /api/, I feel it’s better to wrap all the routes with
’namespace :api do’

Regards,

Joseph

    member do 
      match '/subscriptions/available'        => 

‘activation_keys#available_subscriptions’, :via => :get
match ‘/subscriptions/:subscription_id’ =>
‘activation_keys#show_subscription’, :via => :get
match ‘/subscriptions’ =>
‘activation_keys#index_subscriptions’, :via => :get
match ‘/subscriptions’ =>
‘activation_keys#create_subscription’, :via => :post
match ‘/subscriptions/:subscription_id’ =>
‘activation_keys#update_subscription’, :via => :put
match ‘/subscriptions/:subscription_id’ =>
‘activation_keys#remove_subscription’, :via => :delete

----- Original Message -----

From: “Thomas McKay” <thomas...@gmail.com <javascript:>>
To: forem...@googlegroups.com <javascript:>
Cc: “Adam Price” <adp...@redhat.com <javascript:>>
Sent: Tuesday, October 29, 2013 12:51:38 AM
Subject: [foreman-dev] Re: example of Foreman V2 API controller and
functional test

Thanks for putting all this together?

One question on this:

Architecture has 3 has_many relationships, so we plan to add the
following

3 nested routes, but this is not ready yet

api/architectures/:id/hostgroups
api/architectures/:id/images
api/architectures/:id/operatingsystems

Do you think this is reasonable for nested routes:

  api_resources :activation_keys, :only => [:show, :destroy, 

:create,

:index, :update] do
member do
match ‘/subscriptions/available’ =>
‘activation_keys#available_subscriptions’, :via => :get
match ‘/subscriptions/:subscription_id’ =>
‘activation_keys#show_subscription’, :via => :get
match ‘/subscriptions’ =>
‘activation_keys#index_subscriptions’, :via => :get
match ‘/subscriptions’ =>
‘activation_keys#create_subscription’, :via => :post
match ‘/subscriptions/:subscription_id’ =>
‘activation_keys#update_subscription’, :via => :put
match ‘/subscriptions/:subscription_id’ =>
‘activation_keys#remove_subscription’, :via => :delete

Also, what is the format of results to a call to GET
/activation_keys/2/subscriptions? Is it the same format as
/subscriptions

with data specific to act key 2 context?

On Monday, October 28, 2013 6:17:45 PM UTC-4, Joseph Magen wrote:

Adam,

To see an example of Foreman API v2, you can view the branch
https://github.com/isratrade/foreman/tree/3491_v2

Note that this is not merged yet in Foreman ‘develop’ branch.

I’m using architectures as a basic CRUD example. Go to
/api/architectures
(with version=2 in header) and you should see something like this

{
“total”: 4,
“subtotal”: 4,
“page”: 1,
“per_page”: 20,
“search”: null,
“sort”: {
“by”: null,
“order”: null
},
“results”: [
{
“name”: “i386”,
“id”: 2,
“created_at”: “2010-08-15T10:15:27Z”,
“updated_at”: “2010-08-15T10:15:27Z”
},
{
“name”: “Sparc”,
“id”: 3,
“created_at”: “2012-01-02T15:42:28Z”,
“updated_at”: “2012-01-02T15:42:28Z”
},
{
“name”: “armv5tel”,
“id”: 8,
“created_at”: “2012-07-16T09:19:16Z”,
“updated_at”: “2012-07-16T09:19:16Z”
},
{
“name”: “x86_64”,
“id”: 1,
“created_at”: “2010-08-15T10:15:27Z”,
“updated_at”: “2013-09-03T14:34:45Z”
}
]
}

If you go to /api/architectures/2, you should see

{
“architecture”: {
“name”: “i386”,
“id”: 2,
“created_at”: “2010-08-15T10:15:27Z”,
“updated_at”: “2010-08-15T10:15:27Z”
}
}

Note: TBD is the root_name will go away or it will be called
something

else.

Architecture has 3 has_many relationships, so we plan to add the
following
3 nested routes, but this is not ready yet

api/architectures/:id/hostgroups
api/architectures/:id/images
api/architectures/:id/operatingsystems

Also, we may include none, one or all of the relationship data in
the

‘show’ response. It’s dependent on each object.

I used a RABL layout to show the metadata on each :index action.
See

https://github.com/isratrade/foreman/blob/3491_v2/app/views/api/v2/layouts/index_layout.json.erb

{
“total”: <%= @total.to_json %>,
“subtotal”: <%= @subtotal.to_json %>,
“page”: <%= @page.to_json %>,
“per_page”: <%= @per_page.to_json %>,
“search”: <%= @search.to_json.html_safe %>,
“sort”: {
“by”: <%= @by.to_json.html_safe %>,
“order”: <%= @order.to_json.html_safe %>
},
"<%= “#{@root_node_name}” %>": <%= yield %>
}

In Api:V2::BaseController, I have two callbacks to get the instance
variables for the layout above.
Note, that I added the gem ‘rails3_before_render’ to get the method
before_render.

https://github.com/isratrade/foreman/blob/3491_v2/app/controllers/api/v2/base_controller.rb

  before_filter :root_node_name, :only => :index 
  before_render :get_metadata, :only => :index 
  layout 'api/v2/layouts/index_layout', :only => :index 

The Rabl templates for architectures are found at

https://github.com/isratrade/foreman/tree/3491_v2/app/views/api/v2/architectures

If interested, there is also a Rabl initializer at

https://github.com/isratrade/foreman/blob/3491_v2/config/initializers/rabl_init.rb

that was needed for v2, since we couldn’t change the global Rabl
default

settings. If we did, it would break v1.

Basic functional tests for the api v2 architecture controller is at

https://github.com/isratrade/foreman/blob/3491_v2/test/functional/api/v2/architectures_controller_test.rb

I tested the metadata response only in one controller (locations)
that

you
can see at

https://github.com/isratrade/foreman/blob/3491_v2/test/functional/api/v2/locations_controller_test.rb#L86

I hope that helps. Let me know if you have any questions.

Regards,

Joseph


You received this message because you are subscribed to the Google
Groups

“foreman-dev” group.
To unsubscribe from this group and stop receiving emails from it, send
an

email to foreman-dev...@googlegroups.com <javascript:>.
For more options, visit https://groups.google.com/groups/opt_out.


You received this message because you are subscribed to the Google
Groups
"foreman-dev" group.
To unsubscribe from this group and stop receiving emails from it, send
an
email to foreman-dev...@googlegroups.com <javascript:>.
For more options, visit https://groups.google.com/groups/opt_out.

> From: "Thomas McKay" <thomasfmckay@gmail.com>
> To: foreman-dev@googlegroups.com
> Cc: "Adam Price" <adprice@redhat.com>
> Sent: Tuesday, October 29, 2013 4:21:48 PM
> Subject: Re: [foreman-dev] Re: example of Foreman V2 API controller and functional test
>
>
>
> >
> > > Also, what is the format of results to a call to GET
> > > /activation_keys/2/subscriptions? Is it the same format as
> > /subscriptions
> > > with data specific to act key 2 context?
> >
> > yes, same format.
> >
> >
> Taking subscriptions on activation key as an example, there is a quantity
> with the association, how is that represented?
>
> POST /activation_keys/2/subscriptions {subscription_id: 3, quantity: 1}
> --> { ??? }

POST/PUT take data attributes. Using curl, it looks like this

curl -u admin:secret -H 'Accept:application/json,version=2' -H "Content-Type:application/json" -X POST -d "{&quot;subscription_id&quot;:&quot;3&quot;, &quot;quantity&quot;:&quot;1&quot;}" http://0.0.0.0:3000/api/activation_keys/2/subscriptions

The response is usually the object that was created or updated

>
> GET /activation-keys/2/subscriptions
> --> { ??? }

same format as GET subscriptions, but filtered by activation-key id 2

>
> GET /activation-keys/2/subscriptions/3
> --> { ??? }

same format as GET subscriptions/3 (there should be an error if subscription 3 is not associated with activation-key 2

>
> GET /activation-keys/2
> --> { id:2, subscriptions:[{id:3, quantity:1, name:"RHEL 6.4"}]}
>

looks fine

··· ----- Original Message ----- > On Tuesday, October 29, 2013 4:19:58 AM UTC-4, Joseph Magen wrote:

It’s this sort of example that I’d like to see make it into the docs before
the katello devs begin updating the v2 controllers and making hammer cli.

Thanks!

----- Original Message -----

From: “Joseph Magen” <jma...@redhat.com <javascript:>>
To: forem...@googlegroups.com <javascript:>
Cc: “Adam Price” <adp...@redhat.com <javascript:>>
Sent: Tuesday, October 29, 2013 9:54:15 AM
Subject: Re: [foreman-dev] Re: example of Foreman V2 API controller and
functional test

Tom,

For the routes, I would do this

resources :activation_keys, :only => [:show, :destroy, :create, :index,
:update] do
resources :subscriptions, :only => [:available, :show, :index,
:create,
:update, :destroy]
end

You don’t need to use a ‘member do’ loop and then explicitly match each
wrote
to controller for RESTful resources. Nested resources does this for
you.

Also, what does method api_resources do that method resources does not?
It’s
it just adding /api/, I feel it’s better to wrap all the routes with
’namespace :api do’

Regards,

Joseph

    member do
      match '/subscriptions/available'        =>

‘activation_keys#available_subscriptions’, :via => :get
match ‘/subscriptions/:subscription_id’ =>
‘activation_keys#show_subscription’, :via => :get
match ‘/subscriptions’ =>
‘activation_keys#index_subscriptions’, :via => :get
match ‘/subscriptions’ =>
‘activation_keys#create_subscription’, :via => :post
match ‘/subscriptions/:subscription_id’ =>
‘activation_keys#update_subscription’, :via => :put
match ‘/subscriptions/:subscription_id’ =>
‘activation_keys#remove_subscription’, :via => :delete

----- Original Message -----

From: “Thomas McKay” <thomas...@gmail.com <javascript:>>
To: forem...@googlegroups.com <javascript:>
Cc: “Adam Price” <adp...@redhat.com <javascript:>>
Sent: Tuesday, October 29, 2013 12:51:38 AM
Subject: [foreman-dev] Re: example of Foreman V2 API controller and
functional test

Thanks for putting all this together?

One question on this:

Architecture has 3 has_many relationships, so we plan to add the
following

3 nested routes, but this is not ready yet

api/architectures/:id/hostgroups
api/architectures/:id/images
api/architectures/:id/operatingsystems

Do you think this is reasonable for nested routes:

  api_resources :activation_keys, :only => [:show, :destroy,

:create,

:index, :update] do
member do
match ‘/subscriptions/available’ =>
‘activation_keys#available_subscriptions’, :via => :get
match ‘/subscriptions/:subscription_id’ =>
‘activation_keys#show_subscription’, :via => :get
match ‘/subscriptions’ =>
‘activation_keys#index_subscriptions’, :via => :get
match ‘/subscriptions’ =>
‘activation_keys#create_subscription’, :via => :post
match ‘/subscriptions/:subscription_id’ =>
‘activation_keys#update_subscription’, :via => :put
match ‘/subscriptions/:subscription_id’ =>
‘activation_keys#remove_subscription’, :via => :delete

Also, what is the format of results to a call to GET
/activation_keys/2/subscriptions? Is it the same format as
/subscriptions

with data specific to act key 2 context?

On Monday, October 28, 2013 6:17:45 PM UTC-4, Joseph Magen wrote:

Adam,

To see an example of Foreman API v2, you can view the branch
https://github.com/isratrade/foreman/tree/3491_v2

Note that this is not merged yet in Foreman ‘develop’ branch.

I’m using architectures as a basic CRUD example. Go to
/api/architectures
(with version=2 in header) and you should see something like this

{
“total”: 4,
“subtotal”: 4,
“page”: 1,
“per_page”: 20,
“search”: null,
“sort”: {
“by”: null,
“order”: null
},
“results”: [
{
“name”: “i386”,
“id”: 2,
“created_at”: “2010-08-15T10:15:27Z”,
“updated_at”: “2010-08-15T10:15:27Z”
},
{
“name”: “Sparc”,
“id”: 3,
“created_at”: “2012-01-02T15:42:28Z”,
“updated_at”: “2012-01-02T15:42:28Z”
},
{
“name”: “armv5tel”,
“id”: 8,
“created_at”: “2012-07-16T09:19:16Z”,
“updated_at”: “2012-07-16T09:19:16Z”
},
{
“name”: “x86_64”,
“id”: 1,
“created_at”: “2010-08-15T10:15:27Z”,
“updated_at”: “2013-09-03T14:34:45Z”
}
]
}

If you go to /api/architectures/2, you should see

{
“architecture”: {
“name”: “i386”,
“id”: 2,
“created_at”: “2010-08-15T10:15:27Z”,
“updated_at”: “2010-08-15T10:15:27Z”
}
}

Note: TBD is the root_name will go away or it will be called
something

else.

Architecture has 3 has_many relationships, so we plan to add the
following
3 nested routes, but this is not ready yet

api/architectures/:id/hostgroups
api/architectures/:id/images
api/architectures/:id/operatingsystems

Also, we may include none, one or all of the relationship data in
the

‘show’ response. It’s dependent on each object.

I used a RABL layout to show the metadata on each :index action.
See

https://github.com/isratrade/foreman/blob/3491_v2/app/views/api/v2/layouts/index_layout.json.erb

{
“total”: <%= @total.to_json %>,
“subtotal”: <%= @subtotal.to_json %>,
“page”: <%= @page.to_json %>,
“per_page”: <%= @per_page.to_json %>,
“search”: <%= @search.to_json.html_safe %>,
“sort”: {
“by”: <%= @by.to_json.html_safe %>,
“order”: <%= @order.to_json.html_safe %>
},
"<%= “#{@root_node_name}” %>": <%= yield %>
}

In Api:V2::BaseController, I have two callbacks to get the instance
variables for the layout above.
Note, that I added the gem ‘rails3_before_render’ to get the method
before_render.

https://github.com/isratrade/foreman/blob/3491_v2/app/controllers/api/v2/base_controller.rb

  before_filter :root_node_name, :only => :index
  before_render :get_metadata, :only => :index
  layout 'api/v2/layouts/index_layout', :only => :index

The Rabl templates for architectures are found at

https://github.com/isratrade/foreman/tree/3491_v2/app/views/api/v2/architectures

If interested, there is also a Rabl initializer at

https://github.com/isratrade/foreman/blob/3491_v2/config/initializers/rabl_init.rb

that was needed for v2, since we couldn’t change the global Rabl
default

settings. If we did, it would break v1.

Basic functional tests for the api v2 architecture controller is at

https://github.com/isratrade/foreman/blob/3491_v2/test/functional/api/v2/architectures_controller_test.rb

I tested the metadata response only in one controller (locations)
that

you
can see at

https://github.com/isratrade/foreman/blob/3491_v2/test/functional/api/v2/locations_controller_test.rb#L86

I hope that helps. Let me know if you have any questions.

Regards,

Joseph


You received this message because you are subscribed to the Google
Groups

“foreman-dev” group.
To unsubscribe from this group and stop receiving emails from it, send
an

email to foreman-dev...@googlegroups.com <javascript:>.
For more options, visit https://groups.google.com/groups/opt_out.


You received this message because you are subscribed to the Google
Groups
"foreman-dev" group.
To unsubscribe from this group and stop receiving emails from it, send
an
email to foreman-dev...@googlegroups.com <javascript:>.
For more options, visit https://groups.google.com/groups/opt_out.


You received this message because you are subscribed to the Google Groups
"foreman-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an
email to foreman-dev+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

>
>
>
> > From: "Thomas McKay" <thomas...@gmail.com <javascript:>>
> > To: forem...@googlegroups.com <javascript:>
> > Cc: "Adam Price" <adp...@redhat.com <javascript:>>
> > Sent: Tuesday, October 29, 2013 4:21:48 PM
> > Subject: Re: [foreman-dev] Re: example of Foreman V2 API controller and
> functional test
> >
> >
> >
> > >
> > > > Also, what is the format of results to a call to GET
> > > > /activation_keys/2/subscriptions? Is it the same format as
> > > /subscriptions
> > > > with data specific to act key 2 context?
> > >
> > > yes, same format.
> > >
> > >
> > Taking subscriptions on activation key as an example, there is a
> quantity
> > with the association, how is that represented?
> >
> > POST /activation_keys/2/subscriptions {subscription_id: 3, quantity: 1}
> > --> { ??? }
>
> POST/PUT take data attributes. Using curl, it looks like this
>
> curl -u admin:secret -H 'Accept:application/json,version=2' -H
> "Content-Type:application/json" -X POST -d "{&quot;subscription_id&quot;:&quot;3&quot;,
> &quot;quantity&quot;:&quot;1&quot;}"
> http://0.0.0.0:3000/api/activation_keys/2/subscriptions
>
> The response is usually the object that was created or updated
>

So if I wished to add a subscription relation to an activation_key, should
I be PUT /activation_keys/2 w/ updated activation_key attributes, or should
I be PUT /activation_keys/2/subscriptions w/ just relationship information?

I think my confusion is whether the nested resources are "special" or just
alternative paths to the original resources in the context of the parent
resource.

··· On Tuesday, October 29, 2013 11:16:07 AM UTC-4, Joseph Magen wrote: > ----- Original Message ----- > > On Tuesday, October 29, 2013 4:19:58 AM UTC-4, Joseph Magen wrote:

GET /activation-keys/2/subscriptions
–> { ??? }

same format as GET subscriptions, but filtered by activation-key id 2

GET /activation-keys/2/subscriptions/3
–> { ??? }

same format as GET subscriptions/3 (there should be an error if
subscription 3 is not associated with activation-key 2

GET /activation-keys/2
–> { id:2, subscriptions:[{id:3, quantity:1, name:“RHEL 6.4”}]}

looks fine

It’s this sort of example that I’d like to see make it into the docs
before
the katello devs begin updating the v2 controllers and making hammer
cli.

Thanks!

----- Original Message -----

From: “Joseph Magen” <jma...@redhat.com <javascript:>>
To: forem...@googlegroups.com <javascript:>
Cc: “Adam Price” <adp...@redhat.com <javascript:>>
Sent: Tuesday, October 29, 2013 9:54:15 AM
Subject: Re: [foreman-dev] Re: example of Foreman V2 API controller
and

functional test

Tom,

For the routes, I would do this

resources :activation_keys, :only => [:show, :destroy, :create,
:index,

:update] do
resources :subscriptions, :only => [:available, :show, :index,
:create,
:update, :destroy]
end

You don’t need to use a ‘member do’ loop and then explicitly match
each

wrote

to controller for RESTful resources. Nested resources does this for
you.

Also, what does method api_resources do that method resources does
not?

It’s

it just adding /api/, I feel it’s better to wrap all the routes with
’namespace :api do’

Regards,

Joseph

    member do 
      match '/subscriptions/available'        => 

‘activation_keys#available_subscriptions’, :via => :get
match ‘/subscriptions/:subscription_id’ =>
‘activation_keys#show_subscription’, :via => :get
match ‘/subscriptions’ =>
‘activation_keys#index_subscriptions’, :via => :get
match ‘/subscriptions’ =>
‘activation_keys#create_subscription’, :via => :post
match ‘/subscriptions/:subscription_id’ =>
‘activation_keys#update_subscription’, :via => :put
match ‘/subscriptions/:subscription_id’ =>
‘activation_keys#remove_subscription’, :via => :delete

----- Original Message -----

From: “Thomas McKay” <thomas...@gmail.com <javascript:>>
To: forem...@googlegroups.com <javascript:>
Cc: “Adam Price” <adp...@redhat.com <javascript:>>
Sent: Tuesday, October 29, 2013 12:51:38 AM
Subject: [foreman-dev] Re: example of Foreman V2 API controller
and

functional test

Thanks for putting all this together?

One question on this:

Architecture has 3 has_many relationships, so we plan to add the
following

3 nested routes, but this is not ready yet

api/architectures/:id/hostgroups
api/architectures/:id/images
api/architectures/:id/operatingsystems

Do you think this is reasonable for nested routes:

  api_resources :activation_keys, :only => [:show, :destroy, 

:create,

:index, :update] do
member do
match ‘/subscriptions/available’ =>
‘activation_keys#available_subscriptions’, :via => :get
match ‘/subscriptions/:subscription_id’ =>
‘activation_keys#show_subscription’, :via => :get
match ‘/subscriptions’ =>
‘activation_keys#index_subscriptions’, :via => :get
match ‘/subscriptions’ =>
‘activation_keys#create_subscription’, :via => :post
match ‘/subscriptions/:subscription_id’ =>
‘activation_keys#update_subscription’, :via => :put
match ‘/subscriptions/:subscription_id’ =>
‘activation_keys#remove_subscription’, :via => :delete

Also, what is the format of results to a call to GET
/activation_keys/2/subscriptions? Is it the same format as
/subscriptions

with data specific to act key 2 context?

On Monday, October 28, 2013 6:17:45 PM UTC-4, Joseph Magen wrote:

Adam,

To see an example of Foreman API v2, you can view the branch
https://github.com/isratrade/foreman/tree/3491_v2

Note that this is not merged yet in Foreman ‘develop’ branch.

I’m using architectures as a basic CRUD example. Go to
/api/architectures
(with version=2 in header) and you should see something like
this

{
“total”: 4,
“subtotal”: 4,
“page”: 1,
“per_page”: 20,
“search”: null,
“sort”: {
“by”: null,
“order”: null
},
“results”: [
{
“name”: “i386”,
“id”: 2,
“created_at”: “2010-08-15T10:15:27Z”,
“updated_at”: “2010-08-15T10:15:27Z”
},
{
“name”: “Sparc”,
“id”: 3,
“created_at”: “2012-01-02T15:42:28Z”,
“updated_at”: “2012-01-02T15:42:28Z”
},
{
“name”: “armv5tel”,
“id”: 8,
“created_at”: “2012-07-16T09:19:16Z”,
“updated_at”: “2012-07-16T09:19:16Z”
},
{
“name”: “x86_64”,
“id”: 1,
“created_at”: “2010-08-15T10:15:27Z”,
“updated_at”: “2013-09-03T14:34:45Z”
}
]
}

If you go to /api/architectures/2, you should see

{
“architecture”: {
“name”: “i386”,
“id”: 2,
“created_at”: “2010-08-15T10:15:27Z”,
“updated_at”: “2010-08-15T10:15:27Z”
}
}

Note: TBD is the root_name will go away or it will be called
something

else.

Architecture has 3 has_many relationships, so we plan to add the
following
3 nested routes, but this is not ready yet

api/architectures/:id/hostgroups
api/architectures/:id/images
api/architectures/:id/operatingsystems

Also, we may include none, one or all of the relationship data
in

the

‘show’ response. It’s dependent on each object.

I used a RABL layout to show the metadata on each :index action.
See

https://github.com/isratrade/foreman/blob/3491_v2/app/views/api/v2/layouts/index_layout.json.erb

{
“total”: <%= @total.to_json %>,
“subtotal”: <%= @subtotal.to_json %>,
“page”: <%= @page.to_json %>,
“per_page”: <%= @per_page.to_json %>,
“search”: <%= @search.to_json.html_safe %>,
“sort”: {
“by”: <%= @by.to_json.html_safe %>,
“order”: <%= @order.to_json.html_safe %>
},
"<%= “#{@root_node_name}” %>": <%= yield %>
}

In Api:V2::BaseController, I have two callbacks to get the
instance

variables for the layout above.
Note, that I added the gem ‘rails3_before_render’ to get the
method

before_render.

https://github.com/isratrade/foreman/blob/3491_v2/app/controllers/api/v2/base_controller.rb

  before_filter :root_node_name, :only => :index 
  before_render :get_metadata, :only => :index 
  layout 'api/v2/layouts/index_layout', :only => :index 

The Rabl templates for architectures are found at

https://github.com/isratrade/foreman/tree/3491_v2/app/views/api/v2/architectures

If interested, there is also a Rabl initializer at

https://github.com/isratrade/foreman/blob/3491_v2/config/initializers/rabl_init.rb

that was needed for v2, since we couldn’t change the global Rabl
default

settings. If we did, it would break v1.

Basic functional tests for the api v2 architecture controller is
at

https://github.com/isratrade/foreman/blob/3491_v2/test/functional/api/v2/architectures_controller_test.rb

I tested the metadata response only in one controller
(locations)

that

you
can see at

https://github.com/isratrade/foreman/blob/3491_v2/test/functional/api/v2/locations_controller_test.rb#L86

I hope that helps. Let me know if you have any questions.

Regards,

Joseph


You received this message because you are subscribed to the Google
Groups

“foreman-dev” group.
To unsubscribe from this group and stop receiving emails from it,
send

an

email to foreman-dev...@googlegroups.com <javascript:>.
For more options, visit https://groups.google.com/groups/opt_out.


You received this message because you are subscribed to the Google
Groups
"foreman-dev" group.
To unsubscribe from this group and stop receiving emails from it,
send

an

email to foreman-dev...@googlegroups.com <javascript:>.
For more options, visit https://groups.google.com/groups/opt_out.


You received this message because you are subscribed to the Google
Groups
"foreman-dev" group.
To unsubscribe from this group and stop receiving emails from it, send
an
email to foreman-dev...@googlegroups.com <javascript:>.
For more options, visit https://groups.google.com/groups/opt_out.

> From: "Thomas McKay" <thomasfmckay@gmail.com>
> To: foreman-dev@googlegroups.com
> Cc: "Adam Price" <adprice@redhat.com>
> Sent: Tuesday, October 29, 2013 5:25:18 PM
> Subject: Re: [foreman-dev] Re: example of Foreman V2 API controller and functional test
>
>
>
> >
> >
> >
> > > From: "Thomas McKay" <thomas...@gmail.com <javascript:>>
> > > To: forem...@googlegroups.com <javascript:>
> > > Cc: "Adam Price" <adp...@redhat.com <javascript:>>
> > > Sent: Tuesday, October 29, 2013 4:21:48 PM
> > > Subject: Re: [foreman-dev] Re: example of Foreman V2 API controller and
> > functional test
> > >
> > >
> > >
> > > >
> > > > > Also, what is the format of results to a call to GET
> > > > > /activation_keys/2/subscriptions? Is it the same format as
> > > > /subscriptions
> > > > > with data specific to act key 2 context?
> > > >
> > > > yes, same format.
> > > >
> > > >
> > > Taking subscriptions on activation key as an example, there is a
> > quantity
> > > with the association, how is that represented?
> > >
> > > POST /activation_keys/2/subscriptions {subscription_id: 3, quantity: 1}
> > > --> { ??? }
> >
> > POST/PUT take data attributes. Using curl, it looks like this
> >
> > curl -u admin:secret -H 'Accept:application/json,version=2' -H
> > "Content-Type:application/json" -X POST -d "{&quot;subscription_id&quot;:&quot;3&quot;,
> > &quot;quantity&quot;:&quot;1&quot;}"
> > http://0.0.0.0:3000/api/activation_keys/2/subscriptions
> >
> > The response is usually the object that was created or updated
> >
>
> So if I wished to add a subscription relation to an activation_key, should
> I be PUT /activation_keys/2 w/ updated activation_key attributes, or should
> I be PUT /activation_keys/2/subscriptions w/ just relationship information?
>
> I think my confusion is whether the nested resources are "special" or just
> alternative paths to the original resources in the context of the parent
> resource.

To create a new subscription, the RESTful way is to POST to the resource, in this case, subscription. To update, you use PUT on the object. For nested routes, Rails generates a param *_id. In our case, activation_keys/2/subscriptions generated a param['activation_key_id'] => 2 and the router routes to the subscriptions controller and the action index. The code in subscriptions#index needs to take into account param['activation_key_id']. Otherwise, activation_keys/2/subscriptions and /subscriptions will do the same thing. Both perform the action subscriptions#index

··· ----- Original Message ----- > On Tuesday, October 29, 2013 11:16:07 AM UTC-4, Joseph Magen wrote: > > ----- Original Message ----- > > > On Tuesday, October 29, 2013 4:19:58 AM UTC-4, Joseph Magen wrote:

GET /activation-keys/2/subscriptions
–> { ??? }

same format as GET subscriptions, but filtered by activation-key id 2

GET /activation-keys/2/subscriptions/3
–> { ??? }

same format as GET subscriptions/3 (there should be an error if
subscription 3 is not associated with activation-key 2

GET /activation-keys/2
–> { id:2, subscriptions:[{id:3, quantity:1, name:“RHEL 6.4”}]}

looks fine

It’s this sort of example that I’d like to see make it into the docs
before
the katello devs begin updating the v2 controllers and making hammer
cli.

Thanks!

----- Original Message -----

From: “Joseph Magen” <jma...@redhat.com <javascript:>>
To: forem...@googlegroups.com <javascript:>
Cc: “Adam Price” <adp...@redhat.com <javascript:>>
Sent: Tuesday, October 29, 2013 9:54:15 AM
Subject: Re: [foreman-dev] Re: example of Foreman V2 API controller
and

functional test

Tom,

For the routes, I would do this

resources :activation_keys, :only => [:show, :destroy, :create,
:index,

:update] do
resources :subscriptions, :only => [:available, :show, :index,
:create,
:update, :destroy]
end

You don’t need to use a ‘member do’ loop and then explicitly match
each

wrote

to controller for RESTful resources. Nested resources does this for
you.

Also, what does method api_resources do that method resources does
not?

It’s

it just adding /api/, I feel it’s better to wrap all the routes with
’namespace :api do’

Regards,

Joseph

    member do
      match '/subscriptions/available'        =>

‘activation_keys#available_subscriptions’, :via => :get
match ‘/subscriptions/:subscription_id’ =>
‘activation_keys#show_subscription’, :via => :get
match ‘/subscriptions’ =>
‘activation_keys#index_subscriptions’, :via => :get
match ‘/subscriptions’ =>
‘activation_keys#create_subscription’, :via => :post
match ‘/subscriptions/:subscription_id’ =>
‘activation_keys#update_subscription’, :via => :put
match ‘/subscriptions/:subscription_id’ =>
‘activation_keys#remove_subscription’, :via => :delete

----- Original Message -----

From: “Thomas McKay” <thomas...@gmail.com <javascript:>>
To: forem...@googlegroups.com <javascript:>
Cc: “Adam Price” <adp...@redhat.com <javascript:>>
Sent: Tuesday, October 29, 2013 12:51:38 AM
Subject: [foreman-dev] Re: example of Foreman V2 API controller
and

functional test

Thanks for putting all this together?

One question on this:

Architecture has 3 has_many relationships, so we plan to add the
following

3 nested routes, but this is not ready yet

api/architectures/:id/hostgroups
api/architectures/:id/images
api/architectures/:id/operatingsystems

Do you think this is reasonable for nested routes:

  api_resources :activation_keys, :only => [:show, :destroy,

:create,

:index, :update] do
member do
match ‘/subscriptions/available’ =>
‘activation_keys#available_subscriptions’, :via => :get
match ‘/subscriptions/:subscription_id’ =>
‘activation_keys#show_subscription’, :via => :get
match ‘/subscriptions’ =>
‘activation_keys#index_subscriptions’, :via => :get
match ‘/subscriptions’ =>
‘activation_keys#create_subscription’, :via => :post
match ‘/subscriptions/:subscription_id’ =>
‘activation_keys#update_subscription’, :via => :put
match ‘/subscriptions/:subscription_id’ =>
‘activation_keys#remove_subscription’, :via => :delete

Also, what is the format of results to a call to GET
/activation_keys/2/subscriptions? Is it the same format as
/subscriptions

with data specific to act key 2 context?

On Monday, October 28, 2013 6:17:45 PM UTC-4, Joseph Magen wrote:

Adam,

To see an example of Foreman API v2, you can view the branch
https://github.com/isratrade/foreman/tree/3491_v2

Note that this is not merged yet in Foreman ‘develop’ branch.

I’m using architectures as a basic CRUD example. Go to
/api/architectures
(with version=2 in header) and you should see something like
this

{
“total”: 4,
“subtotal”: 4,
“page”: 1,
“per_page”: 20,
“search”: null,
“sort”: {
“by”: null,
“order”: null
},
“results”: [
{
“name”: “i386”,
“id”: 2,
“created_at”: “2010-08-15T10:15:27Z”,
“updated_at”: “2010-08-15T10:15:27Z”
},
{
“name”: “Sparc”,
“id”: 3,
“created_at”: “2012-01-02T15:42:28Z”,
“updated_at”: “2012-01-02T15:42:28Z”
},
{
“name”: “armv5tel”,
“id”: 8,
“created_at”: “2012-07-16T09:19:16Z”,
“updated_at”: “2012-07-16T09:19:16Z”
},
{
“name”: “x86_64”,
“id”: 1,
“created_at”: “2010-08-15T10:15:27Z”,
“updated_at”: “2013-09-03T14:34:45Z”
}
]
}

If you go to /api/architectures/2, you should see

{
“architecture”: {
“name”: “i386”,
“id”: 2,
“created_at”: “2010-08-15T10:15:27Z”,
“updated_at”: “2010-08-15T10:15:27Z”
}
}

Note: TBD is the root_name will go away or it will be called
something

else.

Architecture has 3 has_many relationships, so we plan to add the
following
3 nested routes, but this is not ready yet

api/architectures/:id/hostgroups
api/architectures/:id/images
api/architectures/:id/operatingsystems

Also, we may include none, one or all of the relationship data
in

the

‘show’ response. It’s dependent on each object.

I used a RABL layout to show the metadata on each :index action.
See

https://github.com/isratrade/foreman/blob/3491_v2/app/views/api/v2/layouts/index_layout.json.erb

{
“total”: <%= @total.to_json %>,
“subtotal”: <%= @subtotal.to_json %>,
“page”: <%= @page.to_json %>,
“per_page”: <%= @per_page.to_json %>,
“search”: <%= @search.to_json.html_safe %>,
“sort”: {
“by”: <%= @by.to_json.html_safe %>,
“order”: <%= @order.to_json.html_safe %>
},
"<%= “#{@root_node_name}” %>": <%= yield %>
}

In Api:V2::BaseController, I have two callbacks to get the
instance

variables for the layout above.
Note, that I added the gem ‘rails3_before_render’ to get the
method

before_render.

https://github.com/isratrade/foreman/blob/3491_v2/app/controllers/api/v2/base_controller.rb

  before_filter :root_node_name, :only => :index
  before_render :get_metadata, :only => :index
  layout 'api/v2/layouts/index_layout', :only => :index

The Rabl templates for architectures are found at

https://github.com/isratrade/foreman/tree/3491_v2/app/views/api/v2/architectures

If interested, there is also a Rabl initializer at

https://github.com/isratrade/foreman/blob/3491_v2/config/initializers/rabl_init.rb

that was needed for v2, since we couldn’t change the global Rabl
default

settings. If we did, it would break v1.

Basic functional tests for the api v2 architecture controller is
at

https://github.com/isratrade/foreman/blob/3491_v2/test/functional/api/v2/architectures_controller_test.rb

I tested the metadata response only in one controller
(locations)

that

you
can see at

https://github.com/isratrade/foreman/blob/3491_v2/test/functional/api/v2/locations_controller_test.rb#L86

I hope that helps. Let me know if you have any questions.

Regards,

Joseph


You received this message because you are subscribed to the Google
Groups

“foreman-dev” group.
To unsubscribe from this group and stop receiving emails from it,
send

an

email to foreman-dev...@googlegroups.com <javascript:>.
For more options, visit https://groups.google.com/groups/opt_out.


You received this message because you are subscribed to the Google
Groups
"foreman-dev" group.
To unsubscribe from this group and stop receiving emails from it,
send

an

email to foreman-dev...@googlegroups.com <javascript:>.
For more options, visit https://groups.google.com/groups/opt_out.


You received this message because you are subscribed to the Google
Groups
"foreman-dev" group.
To unsubscribe from this group and stop receiving emails from it, send
an
email to foreman-dev...@googlegroups.com <javascript:>.
For more options, visit https://groups.google.com/groups/opt_out.


You received this message because you are subscribed to the Google Groups
"foreman-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an
email to foreman-dev+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

>
>
>
> > From: "Thomas McKay" <thomas...@gmail.com <javascript:>>
> > To: forem...@googlegroups.com <javascript:>
> > Cc: "Adam Price" <adp...@redhat.com <javascript:>>
> > Sent: Tuesday, October 29, 2013 5:25:18 PM
> > Subject: Re: [foreman-dev] Re: example of Foreman V2 API controller and
> functional test
> >
> >
> >
> > >
> > >
> > >
> > > > From: "Thomas McKay" <thomas...@gmail.com <javascript:>>
> > > > To: forem...@googlegroups.com <javascript:>
> > > > Cc: "Adam Price" <adp...@redhat.com <javascript:>>
> > > > Sent: Tuesday, October 29, 2013 4:21:48 PM
> > > > Subject: Re: [foreman-dev] Re: example of Foreman V2 API controller
> and
> > > functional test
> > > >
> > > >
> > > >
> > > > >
> > > > > > Also, what is the format of results to a call to GET
> > > > > > /activation_keys/2/subscriptions? Is it the same format as
> > > > > /subscriptions
> > > > > > with data specific to act key 2 context?
> > > > >
> > > > > yes, same format.
> > > > >
> > > > >
> > > > Taking subscriptions on activation key as an example, there is a
> > > quantity
> > > > with the association, how is that represented?
> > > >
> > > > POST /activation_keys/2/subscriptions {subscription_id: 3, quantity:
> 1}
> > > > --> { ??? }
> > >
> > > POST/PUT take data attributes. Using curl, it looks like this
> > >
> > > curl -u admin:secret -H 'Accept:application/json,version=2' -H
> > > "Content-Type:application/json" -X POST -d
> "{&quot;subscription_id&quot;:&quot;3&quot;,
> > > &quot;quantity&quot;:&quot;1&quot;}"
> > > http://0.0.0.0:3000/api/activation_keys/2/subscriptions
> > >
> > > The response is usually the object that was created or updated
> > >
> >
> > So if I wished to add a subscription relation to an activation_key,
> should
> > I be PUT /activation_keys/2 w/ updated activation_key attributes, or
> should
> > I be PUT /activation_keys/2/subscriptions w/ just relationship
> information?
> >
> > I think my confusion is whether the nested resources are "special" or
> just
> > alternative paths to the original resources in the context of the parent
> > resource.
>
> To create a new subscription, the RESTful way is to POST to the resource,
> in this case, subscription. To update, you use PUT on the object. For
> nested routes, Rails generates a param *_id. In our case,
> activation_keys/2/subscriptions generated a param['activation_key_id'] => 2
> and the router routes to the subscriptions controller and the action index.
> The code in subscriptions#index needs to take into account
> param['activation_key_id']. Otherwise, activation_keys/2/subscriptions and
> /subscriptions will do the same thing. Both perform the action
> subscriptions#index
>
>
Interesting but not really what I'd want in this case. I'm not sure I'd
want the /activation_keys/2/subscriptions and /subscriptions to both go to
subscriptions_controller, but rather the nested resource to go to the
activation_keys_controller. Not sure I'm a fan of having
subscriptions_controller have activation_keys_business logic in this case
(and in cases where an engine would be adding nested resources for
relations).

I'll code up activation keys later this week and see how it goes.

Thanks!

··· On Tuesday, October 29, 2013 3:49:18 PM UTC-4, Joseph Magen wrote: > ----- Original Message ----- > > On Tuesday, October 29, 2013 11:16:07 AM UTC-4, Joseph Magen wrote: > > > ----- Original Message ----- > > > > On Tuesday, October 29, 2013 4:19:58 AM UTC-4, Joseph Magen wrote:

GET /activation-keys/2/subscriptions
–> { ??? }

same format as GET subscriptions, but filtered by activation-key id 2

GET /activation-keys/2/subscriptions/3
–> { ??? }

same format as GET subscriptions/3 (there should be an error if
subscription 3 is not associated with activation-key 2

GET /activation-keys/2
–> { id:2, subscriptions:[{id:3, quantity:1, name:“RHEL 6.4”}]}

looks fine

It’s this sort of example that I’d like to see make it into the docs
before
the katello devs begin updating the v2 controllers and making hammer
cli.

Thanks!

----- Original Message -----

From: “Joseph Magen” <jma...@redhat.com <javascript:>>
To: forem...@googlegroups.com <javascript:>
Cc: “Adam Price” <adp...@redhat.com <javascript:>>
Sent: Tuesday, October 29, 2013 9:54:15 AM
Subject: Re: [foreman-dev] Re: example of Foreman V2 API
controller

and

functional test

Tom,

For the routes, I would do this

resources :activation_keys, :only => [:show, :destroy, :create,
:index,

:update] do
resources :subscriptions, :only => [:available, :show, :index,
:create,
:update, :destroy]
end

You don’t need to use a ‘member do’ loop and then explicitly
match

each

wrote

to controller for RESTful resources. Nested resources does this
for

you.

Also, what does method api_resources do that method resources
does

not?

It’s

it just adding /api/, I feel it’s better to wrap all the routes
with

‘namespace :api do’

Regards,

Joseph

    member do 
      match '/subscriptions/available'        => 

‘activation_keys#available_subscriptions’, :via => :get
match ‘/subscriptions/:subscription_id’ =>
‘activation_keys#show_subscription’, :via => :get
match ‘/subscriptions’ =>
‘activation_keys#index_subscriptions’, :via => :get
match ‘/subscriptions’ =>
‘activation_keys#create_subscription’, :via => :post
match ‘/subscriptions/:subscription_id’ =>
‘activation_keys#update_subscription’, :via => :put
match ‘/subscriptions/:subscription_id’ =>
‘activation_keys#remove_subscription’, :via => :delete

----- Original Message -----

From: “Thomas McKay” <thomas...@gmail.com <javascript:>>
To: forem...@googlegroups.com <javascript:>
Cc: “Adam Price” <adp...@redhat.com <javascript:>>
Sent: Tuesday, October 29, 2013 12:51:38 AM
Subject: [foreman-dev] Re: example of Foreman V2 API
controller

and

functional test

Thanks for putting all this together?

One question on this:

Architecture has 3 has_many relationships, so we plan to add
the

following

3 nested routes, but this is not ready yet

api/architectures/:id/hostgroups
api/architectures/:id/images
api/architectures/:id/operatingsystems

Do you think this is reasonable for nested routes:

  api_resources :activation_keys, :only => [:show, 

:destroy,

:create,

:index, :update] do
member do
match ‘/subscriptions/available’ =>
‘activation_keys#available_subscriptions’, :via => :get
match ‘/subscriptions/:subscription_id’ =>
‘activation_keys#show_subscription’, :via => :get
match ‘/subscriptions’ =>
‘activation_keys#index_subscriptions’, :via => :get
match ‘/subscriptions’ =>
‘activation_keys#create_subscription’, :via => :post
match ‘/subscriptions/:subscription_id’ =>
‘activation_keys#update_subscription’, :via => :put
match ‘/subscriptions/:subscription_id’ =>
‘activation_keys#remove_subscription’, :via => :delete

Also, what is the format of results to a call to GET
/activation_keys/2/subscriptions? Is it the same format as
/subscriptions

with data specific to act key 2 context?

On Monday, October 28, 2013 6:17:45 PM UTC-4, Joseph Magen > wrote:

Adam,

To see an example of Foreman API v2, you can view the branch
https://github.com/isratrade/foreman/tree/3491_v2

Note that this is not merged yet in Foreman 'develop’
branch.

I’m using architectures as a basic CRUD example. Go to
/api/architectures
(with version=2 in header) and you should see something like
this

{
“total”: 4,
“subtotal”: 4,
“page”: 1,
“per_page”: 20,
“search”: null,
“sort”: {
“by”: null,
“order”: null
},
“results”: [
{
“name”: “i386”,
“id”: 2,
“created_at”: “2010-08-15T10:15:27Z”,
“updated_at”: “2010-08-15T10:15:27Z”
},
{
“name”: “Sparc”,
“id”: 3,
“created_at”: “2012-01-02T15:42:28Z”,
“updated_at”: “2012-01-02T15:42:28Z”
},
{
“name”: “armv5tel”,
“id”: 8,
“created_at”: “2012-07-16T09:19:16Z”,
“updated_at”: “2012-07-16T09:19:16Z”
},
{
“name”: “x86_64”,
“id”: 1,
“created_at”: “2010-08-15T10:15:27Z”,
“updated_at”: “2013-09-03T14:34:45Z”
}
]
}

If you go to /api/architectures/2, you should see

{
“architecture”: {
“name”: “i386”,
“id”: 2,
“created_at”: “2010-08-15T10:15:27Z”,
“updated_at”: “2010-08-15T10:15:27Z”
}
}

Note: TBD is the root_name will go away or it will be called
something

else.

Architecture has 3 has_many relationships, so we plan to add
the

following
3 nested routes, but this is not ready yet

api/architectures/:id/hostgroups
api/architectures/:id/images
api/architectures/:id/operatingsystems

Also, we may include none, one or all of the relationship
data

in

the

‘show’ response. It’s dependent on each object.

I used a RABL layout to show the metadata on each :index
action.

See

https://github.com/isratrade/foreman/blob/3491_v2/app/views/api/v2/layouts/index_layout.json.erb

{
“total”: <%= @total.to_json %>,
“subtotal”: <%= @subtotal.to_json %>,
“page”: <%= @page.to_json %>,
“per_page”: <%= @per_page.to_json %>,
“search”: <%= @search.to_json.html_safe %>,
“sort”: {
“by”: <%= @by.to_json.html_safe %>,
“order”: <%= @order.to_json.html_safe %>
},
"<%= “#{@root_node_name}” %>": <%= yield %>
}

In Api:V2::BaseController, I have two callbacks to get the
instance

variables for the layout above.
Note, that I added the gem ‘rails3_before_render’ to get the
method

before_render.

https://github.com/isratrade/foreman/blob/3491_v2/app/controllers/api/v2/base_controller.rb

  before_filter :root_node_name, :only => :index 
  before_render :get_metadata, :only => :index 
  layout 'api/v2/layouts/index_layout', :only => :index 

The Rabl templates for architectures are found at

https://github.com/isratrade/foreman/tree/3491_v2/app/views/api/v2/architectures

If interested, there is also a Rabl initializer at

https://github.com/isratrade/foreman/blob/3491_v2/config/initializers/rabl_init.rb

that was needed for v2, since we couldn’t change the global
Rabl

default

settings. If we did, it would break v1.

Basic functional tests for the api v2 architecture
controller is

at

https://github.com/isratrade/foreman/blob/3491_v2/test/functional/api/v2/architectures_controller_test.rb

I tested the metadata response only in one controller
(locations)

that

you
can see at

https://github.com/isratrade/foreman/blob/3491_v2/test/functional/api/v2/locations_controller_test.rb#L86

I hope that helps. Let me know if you have any questions.

Regards,

Joseph


You received this message because you are subscribed to the
Google

Groups

“foreman-dev” group.
To unsubscribe from this group and stop receiving emails from
it,

send

an

email to foreman-dev...@googlegroups.com <javascript:>.
For more options, visit
https://groups.google.com/groups/opt_out.


You received this message because you are subscribed to the
Google

Groups

“foreman-dev” group.
To unsubscribe from this group and stop receiving emails from
it,

send

an

email to foreman-dev...@googlegroups.com <javascript:>.
For more options, visit https://groups.google.com/groups/opt_out.


You received this message because you are subscribed to the Google
Groups
"foreman-dev" group.
To unsubscribe from this group and stop receiving emails from it,
send

an

email to foreman-dev...@googlegroups.com <javascript:>.
For more options, visit https://groups.google.com/groups/opt_out.


You received this message because you are subscribed to the Google
Groups
"foreman-dev" group.
To unsubscribe from this group and stop receiving emails from it, send
an
email to foreman-dev...@googlegroups.com <javascript:>.
For more options, visit https://groups.google.com/groups/opt_out.

> From: "Thomas McKay" <thomasfmckay@gmail.com>
> To: foreman-dev@googlegroups.com
> Cc: "Adam Price" <adprice@redhat.com>
> Sent: Tuesday, October 29, 2013 10:03:27 PM
> Subject: Re: [foreman-dev] Re: example of Foreman V2 API controller and functional test
>
>
>
> >
> >
> >
> > > From: "Thomas McKay" <thomas...@gmail.com <javascript:>>
> > > To: forem...@googlegroups.com <javascript:>
> > > Cc: "Adam Price" <adp...@redhat.com <javascript:>>
> > > Sent: Tuesday, October 29, 2013 5:25:18 PM
> > > Subject: Re: [foreman-dev] Re: example of Foreman V2 API controller and
> > functional test
> > >
> > >
> > >
> > > >
> > > >
> > > >
> > > > > From: "Thomas McKay" <thomas...@gmail.com <javascript:>>
> > > > > To: forem...@googlegroups.com <javascript:>
> > > > > Cc: "Adam Price" <adp...@redhat.com <javascript:>>
> > > > > Sent: Tuesday, October 29, 2013 4:21:48 PM
> > > > > Subject: Re: [foreman-dev] Re: example of Foreman V2 API controller
> > and
> > > > functional test
> > > > >
> > > > >
> > > > >
> > > > > >
> > > > > > > Also, what is the format of results to a call to GET
> > > > > > > /activation_keys/2/subscriptions? Is it the same format as
> > > > > > /subscriptions
> > > > > > > with data specific to act key 2 context?
> > > > > >
> > > > > > yes, same format.
> > > > > >
> > > > > >
> > > > > Taking subscriptions on activation key as an example, there is a
> > > > quantity
> > > > > with the association, how is that represented?
> > > > >
> > > > > POST /activation_keys/2/subscriptions {subscription_id: 3, quantity:
> > 1}
> > > > > --> { ??? }
> > > >
> > > > POST/PUT take data attributes. Using curl, it looks like this
> > > >
> > > > curl -u admin:secret -H 'Accept:application/json,version=2' -H
> > > > "Content-Type:application/json" -X POST -d
> > "{&quot;subscription_id&quot;:&quot;3&quot;,
> > > > &quot;quantity&quot;:&quot;1&quot;}"
> > > > http://0.0.0.0:3000/api/activation_keys/2/subscriptions
> > > >
> > > > The response is usually the object that was created or updated
> > > >
> > >
> > > So if I wished to add a subscription relation to an activation_key,
> > should
> > > I be PUT /activation_keys/2 w/ updated activation_key attributes, or
> > should
> > > I be PUT /activation_keys/2/subscriptions w/ just relationship
> > information?
> > >
> > > I think my confusion is whether the nested resources are "special" or
> > just
> > > alternative paths to the original resources in the context of the parent
> > > resource.
> >
> > To create a new subscription, the RESTful way is to POST to the resource,
> > in this case, subscription. To update, you use PUT on the object. For
> > nested routes, Rails generates a param *_id. In our case,
> > activation_keys/2/subscriptions generated a param['activation_key_id'] => 2
> > and the router routes to the subscriptions controller and the action index.
> > The code in subscriptions#index needs to take into account
> > param['activation_key_id']. Otherwise, activation_keys/2/subscriptions and
> > /subscriptions will do the same thing. Both perform the action
> > subscriptions#index
> >
> >
> Interesting but not really what I'd want in this case. I'm not sure I'd
> want the /activation_keys/2/subscriptions and /subscriptions to both go to
> subscriptions_controller, but rather the nested resource to go to the
> activation_keys_controller.

This is the way the Rails router works. If you want to go to the activation_keys_controller, then just do GET /activation_keys/2 and it's mapped to the #show action of the activation_keys_controller

··· ----- Original Message ----- > On Tuesday, October 29, 2013 3:49:18 PM UTC-4, Joseph Magen wrote: > > ----- Original Message ----- > > > On Tuesday, October 29, 2013 11:16:07 AM UTC-4, Joseph Magen wrote: > > > > ----- Original Message ----- > > > > > On Tuesday, October 29, 2013 4:19:58 AM UTC-4, Joseph Magen wrote:

Not sure I’m a fan of having
subscriptions_controller have activation_keys_business logic in this case
(and in cases where an engine would be adding nested resources for
relations).

I’ll code up activation keys later this week and see how it goes.

Thanks!

GET /activation-keys/2/subscriptions
–> { ??? }

same format as GET subscriptions, but filtered by activation-key id 2

GET /activation-keys/2/subscriptions/3
–> { ??? }

same format as GET subscriptions/3 (there should be an error if
subscription 3 is not associated with activation-key 2

GET /activation-keys/2
–> { id:2, subscriptions:[{id:3, quantity:1, name:“RHEL 6.4”}]}

looks fine

It’s this sort of example that I’d like to see make it into the docs
before
the katello devs begin updating the v2 controllers and making hammer
cli.

Thanks!

----- Original Message -----

From: “Joseph Magen” <jma...@redhat.com <javascript:>>
To: forem...@googlegroups.com <javascript:>
Cc: “Adam Price” <adp...@redhat.com <javascript:>>
Sent: Tuesday, October 29, 2013 9:54:15 AM
Subject: Re: [foreman-dev] Re: example of Foreman V2 API
controller

and

functional test

Tom,

For the routes, I would do this

resources :activation_keys, :only => [:show, :destroy, :create,
:index,

:update] do
resources :subscriptions, :only => [:available, :show, :index,
:create,
:update, :destroy]
end

You don’t need to use a ‘member do’ loop and then explicitly
match

each

wrote

to controller for RESTful resources. Nested resources does this
for

you.

Also, what does method api_resources do that method resources
does

not?

It’s

it just adding /api/, I feel it’s better to wrap all the routes
with

‘namespace :api do’

Regards,

Joseph

    member do
      match '/subscriptions/available'        =>

‘activation_keys#available_subscriptions’, :via => :get
match ‘/subscriptions/:subscription_id’ =>
‘activation_keys#show_subscription’, :via => :get
match ‘/subscriptions’ =>
‘activation_keys#index_subscriptions’, :via => :get
match ‘/subscriptions’ =>
‘activation_keys#create_subscription’, :via => :post
match ‘/subscriptions/:subscription_id’ =>
‘activation_keys#update_subscription’, :via => :put
match ‘/subscriptions/:subscription_id’ =>
‘activation_keys#remove_subscription’, :via => :delete

----- Original Message -----

From: “Thomas McKay” <thomas...@gmail.com <javascript:>>
To: forem...@googlegroups.com <javascript:>
Cc: “Adam Price” <adp...@redhat.com <javascript:>>
Sent: Tuesday, October 29, 2013 12:51:38 AM
Subject: [foreman-dev] Re: example of Foreman V2 API
controller

and

functional test

Thanks for putting all this together?

One question on this:

Architecture has 3 has_many relationships, so we plan to add
the

following

3 nested routes, but this is not ready yet

api/architectures/:id/hostgroups
api/architectures/:id/images
api/architectures/:id/operatingsystems

Do you think this is reasonable for nested routes:

  api_resources :activation_keys, :only => [:show,

:destroy,

:create,

:index, :update] do
member do
match ‘/subscriptions/available’ =>
‘activation_keys#available_subscriptions’, :via => :get
match ‘/subscriptions/:subscription_id’ =>
‘activation_keys#show_subscription’, :via => :get
match ‘/subscriptions’ =>
‘activation_keys#index_subscriptions’, :via => :get
match ‘/subscriptions’ =>
‘activation_keys#create_subscription’, :via => :post
match ‘/subscriptions/:subscription_id’ =>
‘activation_keys#update_subscription’, :via => :put
match ‘/subscriptions/:subscription_id’ =>
‘activation_keys#remove_subscription’, :via => :delete

Also, what is the format of results to a call to GET
/activation_keys/2/subscriptions? Is it the same format as
/subscriptions

with data specific to act key 2 context?

On Monday, October 28, 2013 6:17:45 PM UTC-4, Joseph Magen > > wrote:

Adam,

To see an example of Foreman API v2, you can view the branch
https://github.com/isratrade/foreman/tree/3491_v2

Note that this is not merged yet in Foreman 'develop’
branch.

I’m using architectures as a basic CRUD example. Go to
/api/architectures
(with version=2 in header) and you should see something like
this

{
“total”: 4,
“subtotal”: 4,
“page”: 1,
“per_page”: 20,
“search”: null,
“sort”: {
“by”: null,
“order”: null
},
“results”: [
{
“name”: “i386”,
“id”: 2,
“created_at”: “2010-08-15T10:15:27Z”,
“updated_at”: “2010-08-15T10:15:27Z”
},
{
“name”: “Sparc”,
“id”: 3,
“created_at”: “2012-01-02T15:42:28Z”,
“updated_at”: “2012-01-02T15:42:28Z”
},
{
“name”: “armv5tel”,
“id”: 8,
“created_at”: “2012-07-16T09:19:16Z”,
“updated_at”: “2012-07-16T09:19:16Z”
},
{
“name”: “x86_64”,
“id”: 1,
“created_at”: “2010-08-15T10:15:27Z”,
“updated_at”: “2013-09-03T14:34:45Z”
}
]
}

If you go to /api/architectures/2, you should see

{
“architecture”: {
“name”: “i386”,
“id”: 2,
“created_at”: “2010-08-15T10:15:27Z”,
“updated_at”: “2010-08-15T10:15:27Z”
}
}

Note: TBD is the root_name will go away or it will be called
something

else.

Architecture has 3 has_many relationships, so we plan to add
the

following
3 nested routes, but this is not ready yet

api/architectures/:id/hostgroups
api/architectures/:id/images
api/architectures/:id/operatingsystems

Also, we may include none, one or all of the relationship
data

in

the

‘show’ response. It’s dependent on each object.

I used a RABL layout to show the metadata on each :index
action.

See

https://github.com/isratrade/foreman/blob/3491_v2/app/views/api/v2/layouts/index_layout.json.erb

{
“total”: <%= @total.to_json %>,
“subtotal”: <%= @subtotal.to_json %>,
“page”: <%= @page.to_json %>,
“per_page”: <%= @per_page.to_json %>,
“search”: <%= @search.to_json.html_safe %>,
“sort”: {
“by”: <%= @by.to_json.html_safe %>,
“order”: <%= @order.to_json.html_safe %>
},
"<%= “#{@root_node_name}” %>": <%= yield %>
}

In Api:V2::BaseController, I have two callbacks to get the
instance

variables for the layout above.
Note, that I added the gem ‘rails3_before_render’ to get the
method

before_render.

https://github.com/isratrade/foreman/blob/3491_v2/app/controllers/api/v2/base_controller.rb

  before_filter :root_node_name, :only => :index
  before_render :get_metadata, :only => :index
  layout 'api/v2/layouts/index_layout', :only => :index

The Rabl templates for architectures are found at

https://github.com/isratrade/foreman/tree/3491_v2/app/views/api/v2/architectures

If interested, there is also a Rabl initializer at

https://github.com/isratrade/foreman/blob/3491_v2/config/initializers/rabl_init.rb

that was needed for v2, since we couldn’t change the global
Rabl

default

settings. If we did, it would break v1.

Basic functional tests for the api v2 architecture
controller is

at

https://github.com/isratrade/foreman/blob/3491_v2/test/functional/api/v2/architectures_controller_test.rb

I tested the metadata response only in one controller
(locations)

that

you
can see at

https://github.com/isratrade/foreman/blob/3491_v2/test/functional/api/v2/locations_controller_test.rb#L86

I hope that helps. Let me know if you have any questions.

Regards,

Joseph


You received this message because you are subscribed to the
Google

Groups

“foreman-dev” group.
To unsubscribe from this group and stop receiving emails from
it,

send

an

email to foreman-dev...@googlegroups.com <javascript:>.
For more options, visit
https://groups.google.com/groups/opt_out.


You received this message because you are subscribed to the
Google

Groups

“foreman-dev” group.
To unsubscribe from this group and stop receiving emails from
it,

send

an

email to foreman-dev...@googlegroups.com <javascript:>.
For more options, visit https://groups.google.com/groups/opt_out.


You received this message because you are subscribed to the Google
Groups
"foreman-dev" group.
To unsubscribe from this group and stop receiving emails from it,
send

an

email to foreman-dev...@googlegroups.com <javascript:>.
For more options, visit https://groups.google.com/groups/opt_out.


You received this message because you are subscribed to the Google
Groups
"foreman-dev" group.
To unsubscribe from this group and stop receiving emails from it, send
an
email to