Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

restful_resource - (read_)selector handle selected part is removed out-of-band #94

Merged
merged 1 commit into from
May 16, 2024

Conversation

magodo
Copy link
Owner

@magodo magodo commented May 16, 2024

For some composite API responses, where only the subset of the response represents the resource that the user currently tracks. In this case, users use (read_)selector to select the tracked resource from this response. Currently, the provider will always try to apply the selector (query) on the response and return the query result, even if queried out nothing, in which case the follow up modify body process in read function will fail with errors like below:

│ Error: Modifying `body` during Read
...
│ unmarshal the body "": unexpected end of JSON input

This can be triggered by several cases, e.g.:

  1. The selector is not correctly composed
  2. The resource is removed out-of-band

This PR changes the behavior when the query returns nothing, that we will regard this resource as non exist. This has no problem for the 2nd case, but might introduce in-convenience for the 1st case, as user now will need to either import the resource or remove it out-of-band...

This change covers:

  • Resource restful_resource - read_selector
  • Data Source restful_resource - selector

Fix #92

For some *composite* API responses, where only the subset of the response represents the resource that the user currently tracks. In this case, users use `(read_)selector` to select the tracked resource from this response. Currently, the provider will always try to apply the selector (query) on the response and return the query result, even if queried out nothing, in which case the follow up modify body process in read function will fail with errors like below:

```
│ Error: Modifying `body` during Read
...
│ unmarshal the body "": unexpected end of JSON input
```

This can be triggered by several cases, e.g.:

1. The selector is not correctly composed
2. The resource is removed out-of-band

This PR changes the behavior when the query returns nothing, that we will regard this resource as non exist. This has no problem for the 2nd case, but might introduce in-convenience for the 1st case, as user now will need to either import the resource or remove it out-of-band...

This change covers:

- Resource `restful_resource` - `read_selector`
- Data Source `restful_resource` - `selector`
@magodo magodo added the bug Something isn't working label May 16, 2024
@magodo
Copy link
Owner Author

magodo commented May 16, 2024

Manual test performed to simulate the out of band remove.

Start the json server. Then apply the resource using the following config:

terraform {
  required_providers {
    restful = {
      source = "magodo/restful"
    }
  }
}
provider "restful" {
  base_url = "http://localhost:3000"
}

resource "restful_resource" "test" {
  path = "posts"
  body = jsonencode({
    name = "foo"
    age = 1
  })
  update_path = "posts/$(body.id)"
  read_selector = "#(name == \"foo\")"
}

Try updating age to 2 and apply/plan, to make sure everything works as expected.

Then remove this record in the json server managed json file, then run terraform plan, which get the expected result as below, indicating the read during refresh now ends up with removing the resource from state:

Terraform will perform the following actions:

  # restful_resource.test will be created
  + resource "restful_resource" "test" {
      + body          = jsonencode(
            {
              + age  = 1
              + name = "foo"
            }
        )
      + id            = (known after apply)
      + output        = (known after apply)
      + path          = "posts"
      + read_selector = "#(name == \"foo\")"
      + update_path   = "posts/$(body.id)"
    }

Plan: 1 to add, 0 to change, 0 to destroy.

────────────────────────────────────────────────────────────────────────────────────────

Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to
take exactly these actions if you run "terraform apply" now.

@magodo magodo merged commit 27efaf7 into main May 16, 2024
magodo added a commit that referenced this pull request May 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

restful_resource - unmarshal the body "": unexpected end of JSON input
1 participant