Skip to content

Commit 6a148fd

Browse files
committed
Support separate paths for GET, POST, PUT and DELETE
1 parent 0b66d7e commit 6a148fd

File tree

5 files changed

+70
-15
lines changed

5 files changed

+70
-15
lines changed

restapi/api_object.go

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@ import (
1111

1212
type api_object struct {
1313
api_client *api_client
14-
path string
14+
get_path string
15+
post_path string
16+
put_path string
17+
delete_path string
1518
debug bool
1619
id string
1720

@@ -21,24 +24,29 @@ type api_object struct {
2124
}
2225

2326
// Make an api_object to manage a RESTful object in an API
24-
func NewAPIObject (i_client *api_client, i_path string, i_id string, i_data string, i_debug bool) (*api_object, error) {
27+
func NewAPIObject (i_client *api_client, i_get_path string, i_post_path string, i_put_path string, i_delete_path string, i_id string, i_data string, i_debug bool) (*api_object, error) {
2528
if i_debug {
2629
log.Printf("api_object.go: Constructing debug api_object\n")
27-
log.Printf(" path: %s\n", i_path)
2830
log.Printf(" id: %s\n", i_id)
2931
}
3032

3133
obj := api_object{
3234
api_client: i_client,
33-
path: i_path,
35+
get_path: i_get_path,
36+
post_path: i_put_path,
37+
put_path: i_post_path,
38+
delete_path: i_delete_path,
3439
debug: i_debug,
3540
id: i_id,
3641
data: make(map[string]interface{}),
3742
api_data: make(map[string]interface{}),
3843
}
3944

40-
if "" == i_path { return nil, errors.New("No path passed to api_object constructor") }
41-
if "" == i_data { return nil, errors.New("No data passed to api_object constructor") }
45+
if "" == i_get_path { return nil, errors.New("No GET path passed to api_object constructor") }
46+
if "" == i_post_path { return nil, errors.New("No POST path passed to api_object constructor") }
47+
if "" == i_put_path { return nil, errors.New("No PUT path passed to api_object constructor") }
48+
if "" == i_delete_path { return nil, errors.New("No DELETE path passed to api_object constructor") }
49+
if "" == i_data { return nil, errors.New("No data passed to api_object constructor") }
4250

4351
if i_data != ""{
4452
if i_debug { log.Printf("api_object.go: Parsing data: '%s'", i_data) }
@@ -71,7 +79,10 @@ func NewAPIObject (i_client *api_client, i_path string, i_id string, i_data stri
7179
func (obj *api_object) toString() string {
7280
var buffer bytes.Buffer
7381
buffer.WriteString(fmt.Sprintf("id: %s\n", obj.id))
74-
buffer.WriteString(fmt.Sprintf("path: %s\n", obj.path))
82+
buffer.WriteString(fmt.Sprintf("get_path: %s\n", obj.get_path))
83+
buffer.WriteString(fmt.Sprintf("post_path: %s\n", obj.post_path))
84+
buffer.WriteString(fmt.Sprintf("put_path: %s\n", obj.put_path))
85+
buffer.WriteString(fmt.Sprintf("delete_path: %s\n", obj.delete_path))
7586
buffer.WriteString(fmt.Sprintf("debug: %t\n", obj.debug))
7687
buffer.WriteString(fmt.Sprintf("data: %s\n", spew.Sdump(obj.data)))
7788
buffer.WriteString(fmt.Sprintf("api_data: %s\n", spew.Sdump(obj.api_data)))
@@ -139,7 +150,7 @@ func (obj *api_object) create_object() error {
139150
}
140151

141152
b, _ := json.Marshal(obj.data)
142-
res_str, err := obj.api_client.send_request("POST", obj.path, string(b))
153+
res_str, err := obj.api_client.send_request("POST", obj.post_path, string(b))
143154
if err != nil { return err }
144155

145156
/* We will need to sync state as well as get the object's ID */
@@ -167,7 +178,7 @@ func (obj *api_object) read_object() error {
167178
return errors.New("Cannot read an object unless the ID has been set.")
168179
}
169180

170-
res_str, err := obj.api_client.send_request("GET", obj.path + "/" + obj.id, "")
181+
res_str, err := obj.api_client.send_request("GET", obj.get_path + "/" + obj.id, "")
171182
if err != nil { return err }
172183

173184
err = obj.update_state(res_str)
@@ -180,7 +191,7 @@ func (obj *api_object) update_object() error {
180191
}
181192

182193
b, _ := json.Marshal(obj.data)
183-
res_str, err := obj.api_client.send_request("PUT", obj.path + "/" + obj.id, string(b))
194+
res_str, err := obj.api_client.send_request("PUT", obj.put_path + "/" + obj.id, string(b))
184195
if err != nil { return err }
185196

186197
if obj.api_client.write_returns_object {
@@ -199,7 +210,7 @@ func (obj *api_object) delete_object() error {
199210
return nil
200211
}
201212

202-
_, err := obj.api_client.send_request("DELETE", obj.path + "/" + obj.id, "")
213+
_, err := obj.api_client.send_request("DELETE", obj.delete_path + "/" + obj.id, "")
203214
if err != nil { return err }
204215

205216
return nil

restapi/api_object_test.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,10 @@ func TestAPIObject(t *testing.T) {
5959
if test_debug { log.Printf("api_object_test.go: '%s'\n", id) }
6060
o, err := NewAPIObject(
6161
client, /* The HTTP client created above */
62-
"/api/objects", /* path to the "object" in the test server (note: id will automatically be appended) */
62+
"/api/objects", /* path to the "object" in the test server for GET (note: id will automatically be appended) */
63+
"/api/objects", /* path to the "object" in the test server for POST (note: id will automatically be appended) */
64+
"/api/objects", /* path to the "object" in the test server for PUT (note: id will automatically be appended) */
65+
"/api/objects", /* path to the "object" in the test server for DELETE (note: id will automatically be appended) */
6366
"", /* Do not set an ID to force the constructor to verify id_attribute works */
6467
fmt.Sprintf(`{ "Id": "%s" }`, id), /* Start with only an empty JSON object ID as our "data" */
6568
api_object_debug, /* Whether the object's debug is enabled */

restapi/common.go

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,23 @@ import (
1313
func make_api_object(d *schema.ResourceData, m interface{}) (*api_object, error) {
1414
log.Printf("resource_api_object.go: make_api_object routine called for id '%s'\n", d.Id())
1515

16+
17+
get_path := d.Get("path").(string)
18+
post_path := d.Get("path").(string)
19+
put_path := d.Get("path").(string)
20+
delete_path := d.Get("path").(string)
21+
22+
if nil != d.Get("create_path") { post_path = d.Get("create_path").(string) }
23+
if nil != d.Get("read_path") { get_path = d.Get("read_path").(string) }
24+
if nil != d.Get("update_path") { put_path = d.Get("update_path").(string) }
25+
if nil != d.Get("destroy_path") { delete_path = d.Get("destroy_path").(string) }
26+
1627
obj, err := NewAPIObject (
1728
m.(*api_client),
18-
d.Get("path").(string),
29+
get_path,
30+
post_path,
31+
put_path,
32+
delete_path,
1933
d.Id(),
2034
d.Get("data").(string),
2135
d.Get("debug").(bool),

restapi/datasource_api_object.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,16 @@ func dataSourceRestApi() *schema.Resource {
5252

5353

5454
func dataSourceRestApiRead(d *schema.ResourceData, meta interface{}) error {
55+
/* Datasource really only uses GET... but our constructor
56+
supports different paths per action. Just use path for all of them */
57+
path := d.Get("path").(string)
58+
5559
obj, err := NewAPIObject (
5660
meta.(*api_client),
57-
d.Get("path").(string),
61+
path,
62+
path,
63+
path,
64+
path,
5865
d.Id(),
5966
"{}",
6067
d.Get("debug").(bool),
@@ -73,7 +80,7 @@ func dataSourceRestApiRead(d *schema.ResourceData, meta interface{}) error {
7380
/*
7481
Issue a GET to the base path and expect results to come back
7582
*/
76-
res_str, err := obj.api_client.send_request("GET", obj.path, "")
83+
res_str, err := obj.api_client.send_request("GET", path, "")
7784
if err != nil { return err }
7885

7986
/*

restapi/resource_api_object.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,26 @@ func resourceRestApi() *schema.Resource {
2727
Description: "The API path on top of the base URL set in the provider that represents objects of this type on the API server.",
2828
Required: true,
2929
},
30+
"create_path": &schema.Schema{
31+
Type: schema.TypeString,
32+
Description: "Defaults to `path`. The API path on top of the base URL set in the provider that represents where to WRITE (POST) objects of this type on the API server.",
33+
Optional: true,
34+
},
35+
"read_path": &schema.Schema{
36+
Type: schema.TypeString,
37+
Description: "Defaults to `path`. The API path on top of the base URL set in the provider that represents where to READ (GET) objects of this type on the API server.",
38+
Optional: true,
39+
},
40+
"update_path": &schema.Schema{
41+
Type: schema.TypeString,
42+
Description: "Defaults to `path`. The API path on top of the base URL set in the provider that represents where to MODIFY (PUT) objects of this type on the API server.",
43+
Optional: true,
44+
},
45+
"destroy_path": &schema.Schema{
46+
Type: schema.TypeString,
47+
Description: "Defaults to `path`. The API path on top of the base URL set in the provider that represents where to DESTROY (DELETE) objects of this type on the API server.",
48+
Optional: true,
49+
},
3050
"data": &schema.Schema{
3151
Type: schema.TypeString,
3252
Description: "Valid JSON data that this provider will manage with the API server.",

0 commit comments

Comments
 (0)