Table Storage Integration¶
This recipe demonstrates reading and writing Azure Table Storage entities from Java functions using the @TableOutput and @TableInput annotations.
Architecture¶
flowchart TD
HTTP[HTTP Request] --> FA[Function App]
FA -->|TableOutput| WRITE[(Table: entity written)]
READ[(Table: entity read)] -->|TableInput| FA Prerequisites¶
Provide the connection in app settings. A connection string or an identity-based connection is supported. Identity-based connections use a __tableServiceUri suffix:
az functionapp config appsettings set \
--name $APP_NAME \
--resource-group $RG \
--settings "TableConnection__tableServiceUri=https://$STORAGE_NAME.table.core.windows.net"
| CLI element | Explanation |
|---|---|
| Command(s) | az functionapp config appsettings set |
| Key flags | --name, --resource-group, --settings |
| Variables | $APP_NAME, $RG, $STORAGE_NAME |
| Expected result | Azure CLI returns the updated app settings as JSON; confirm the setting is present before continuing. |
For an identity-based connection, grant the managed identity Storage Table Data Reader (input) and Storage Table Data Contributor (output).
Entity Model¶
public class Person {
private String PartitionKey;
private String RowKey;
private String Name;
public String getPartitionKey() { return this.PartitionKey; }
public void setPartitionKey(String key) { this.PartitionKey = key; }
public String getRowKey() { return this.RowKey; }
public void setRowKey(String key) { this.RowKey = key; }
public String getName() { return this.Name; }
public void setName(String name) { this.Name = name; }
}
Output Binding: Write an Entity¶
public class TableFunctions {
@FunctionName("addPerson")
public HttpResponseMessage addPerson(
@HttpTrigger(
name = "req",
methods = {HttpMethod.POST},
authLevel = AuthorizationLevel.FUNCTION,
route = "persons/{partitionKey}/{rowKey}"
) HttpRequestMessage<Optional<Person>> request,
@BindingName("partitionKey") String partitionKey,
@BindingName("rowKey") String rowKey,
@TableOutput(
name = "person",
partitionKey = "{partitionKey}",
rowKey = "{rowKey}",
tableName = "persons",
connection = "TableConnection"
) OutputBinding<Person> person,
final ExecutionContext context
) {
Person outPerson = new Person();
outPerson.setPartitionKey(partitionKey);
outPerson.setRowKey(rowKey);
outPerson.setName(request.getBody().get().getName());
person.setValue(outPerson);
return request.createResponseBuilder(HttpStatus.OK)
.header("Content-Type", "application/json")
.body(outPerson)
.build();
}
}
Input Binding: Read an Entity¶
@FunctionName("getPerson")
public HttpResponseMessage getPerson(
@HttpTrigger(
name = "req",
methods = {HttpMethod.GET},
authLevel = AuthorizationLevel.FUNCTION,
route = "persons/{partitionKey}/{rowKey}"
) HttpRequestMessage<Optional<String>> request,
@TableInput(
name = "person",
partitionKey = "{partitionKey}",
rowKey = "{rowKey}",
tableName = "persons",
connection = "TableConnection"
) Person person,
final ExecutionContext context
) {
if (person == null) {
return request.createResponseBuilder(HttpStatus.NOT_FOUND).build();
}
return request.createResponseBuilder(HttpStatus.OK)
.header("Content-Type", "application/json")
.body(person)
.build();
}