How to determine an optional attribute exists in plugin framework

Hi, I’m writing a provider. For a resource, I wondering how to check if an optional attribute exists.

In Read function, I think it is mainly about the req.State object. Get or GetAttribute includes a lot of type-casting handling, which I don’t need, and It’s hard to tell from returned diagnostics. I’m not sure PathMatches could be a choice or not.

Hi @dreampuf :wave:

If you have a schema that defines an optional attribute, such as the following:

func (e *exampleResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
	resp.Schema = schema.Schema{
		Attributes: map[string]schema.Attribute{
			"configurable_attribute": schema.StringAttribute{
				Optional:            true,
				MarkdownDescription: "Example configurable attribute",
			},
		},
	}
}

Assuming, the associated data model looks as follows:

type exampleResourceData struct {
	ConfigurableAttribute types.String `tfsdk:"configurable_attribute"`
}

Then you can check whether the optional attribute is defined in the plan in the Create method, or in the state in the Read method as follows:

func (e *exampleResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
	var data exampleResourceData

	diags := req.Plan.Get(ctx, &data)
	resp.Diagnostics.Append(diags...)

	if resp.Diagnostics.HasError() {
		return
	}

	if data.ConfigurableAttribute.IsNull() {
		tflog.Info(ctx, "create")
	}

	tflog.Trace(ctx, "created a resource")

	diags = resp.State.Set(ctx, &data)
	resp.Diagnostics.Append(diags...)
}

func (e *exampleResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
	var data exampleResourceData

	diags := req.State.Get(ctx, &data)
	resp.Diagnostics.Append(diags...)

	if resp.Diagnostics.HasError() {
		return
	}

	if data.ConfigurableAttribute.IsNull() {
		tflog.Info(ctx, "read")
	}

	diags = resp.State.Set(ctx, &data)
	resp.Diagnostics.Append(diags...)
}

If the data.ConfigurableAttribute is not null, then you can obtain the string value of the attribute by calling data.ConfigurableAttribute.ValueString() or data.ConfigurableAttribute.ValueStringPointer().

Hi @bendbennett Thanks. That’s exactly what I want.