-
Notifications
You must be signed in to change notification settings - Fork 0
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
DRAFT: [Tables] API Review 1.0.0-preview.1 #1
base: tables-review-pr
Are you sure you want to change the base?
Conversation
|
||
// @public | ||
export type CreateEntityResponse = TableInsertEntityHeaders & { | ||
[propertyName: string]: any; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
WIP: CreateEntityResponse will use generic types
export type CreateEntityResponse<T> = TableInsertEntityHeaders & T & {
// ...
}
|
||
// @public | ||
export interface DeleteEntityOptions extends coreHttp.OperationOptions { | ||
queryOptions?: GeneratedQueryOptions; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We'll need to rename GeneratedQueryOptions
} | ||
|
||
// @public | ||
export type Entity<T> = T & { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Other languages seem to be going with TableEntity
. Is TableEntity
what we want to use across languages?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Entity should also include etag
and timestamp
}; | ||
|
||
// @public | ||
export interface GeneratedQueryOptions { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We may want to rename GeneratedQueryOptions
export type ListEntitiesIterator<T extends object> = PagedAsyncIterableIterator< | ||
T, | ||
ListEntitiesPageResult<T>, | ||
{} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
WIP: We are working on refining the iterator. {}
will be replaced by PageSettings
or removed.
For context this is the interface of PageSettings
/**
* @interface
* An interface that tracks the settings for paged iteration
*/
export interface PageSettings {
/**
* @member {string} [continuationToken] The token that keeps track of where to continue the iterator
*/
continuationToken?: string;
/**
* @member {number} [pageSize] The size of the page during paged iteration
*/
maxPageSize?: number;
}
date?: Date; | ||
requestId?: string; | ||
version?: string; | ||
xMsContinuationNextTableName?: string; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
xMsContinuationNextTableName
should probably be renamed to nextTableName
|
||
// @public | ||
export class TableServiceClient { | ||
constructor(url: string, options?: TableServiceClientOptions); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
WIP: constructor override which accepts SharedKeyCredential
query?: QueryOptions, | ||
options?: ListEntitiesOptions | ||
): Promise<ListEntitiesResponse<T>>; | ||
listTables(query?: QueryOptions, options?: ListTablesOptions): Promise<ListTablesResponse>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
WIP: listTables
will support PagedAsyncIterableIterator
queryOptions?: GeneratedQueryOptions; | ||
requestId?: string; | ||
tableEntityProperties?: { | ||
[propertyName: string]: any; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If possible we should override uses of [propertyName: string]: any]
with generic types
tableName: string, | ||
entity: Entity<T>, | ||
mode?: UpdateMode, | ||
eTag?: string, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we are already passing the entity
, do we need to also pass the eTag
? Or can we just extract it from the entity we were passed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we want to default eTag to "*"
or do we make it required and don't assume "*"
on undefined?
"*"
will force unconditional update
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From the arch board review, we'd like to have etag as optional and default to "*"
// @public | ||
export interface GeneratedQueryOptions { | ||
filter?: string; | ||
format?: OdataMetadataFormat; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So looking at this the actual values the user would pass here are things like this:
"application/json;odata=nometadata"
Is the user expected to modify these strings at all (ie, pass something other applictio/json, like octet-stream, etc..)?
If not is it worth simplifying them? Perhaps:
"none" | "minimal" | "full"
and then translating this in your convenience layer?
} | ||
|
||
// @public | ||
export function odata(strings: TemplateStringsArray, ...values: unknown[]): string; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems somewhat rare to have an exported function without some associated class. How would the user use this - just curious how it ties in.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This helper function will be used as a tagged template literal for escaping any single quotes inside a filter parameter when querying.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is pretty neat!
| "application/json;odata=fullmetadata"; | ||
|
||
// @public | ||
export interface QueryOptions extends Omit<GeneratedQueryOptions, "select"> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I love Omit<> but be aware that it does ugly thing in our doc tool currently.
// @public | ||
export interface TableSetAccessPolicyOptionalParams extends coreHttp.OperationOptions { | ||
requestId?: string; | ||
tableAcl?: SignedIdentifier[]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not familiar with tables but is this always one way (ie only acts as an allowed list, never acts as a deny list?).
export interface TableSetAccessPolicyOptionalParams extends coreHttp.OperationOptions { | ||
requestId?: string; | ||
tableAcl?: SignedIdentifier[]; | ||
timeout?: number; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe we have a rule about this - it has to be timeoutInMs (ie, mention the unit and add 'In').
Also, is this timeout separate from the normal corehttp timeouts? Does it function independently of our normal retries, etc.?
|
||
// @public | ||
export interface TableSetAccessPolicyOptionalParams extends coreHttp.OperationOptions { | ||
requestId?: string; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm curious what this is - I feel like generically we have fields with 'request' in the name all over the place (ie, for http, etc..). Is this something specific o tables (and if so - could it have a more Tables specific name?)
}; | ||
|
||
// @public | ||
export enum UpdateMode { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In Service Bus we've been eschewing enums in favor of just using string unions - no sure if that's an option you'd like to try here or if the 0/1 is better for clients.
So:
export type UpdateMode = "merge" | "replace";
tableName: string, | ||
partitionKey: string, | ||
rowKey: string, | ||
ifMatch: string, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is ifMatch
really not optional? Or is this not the etag
ifMatch?
} | ||
|
||
// @public | ||
export class EdmInt64 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is interesting! We use a long
package in Service Bus and I seem to recall Brian pushing hard to see if we could just use number, etc...
Do you know if we have an "approved" way of representing longer number at this point?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@richardpark-msft, your bring up a good point. We're currently having this conversation with @bterlson, @xirzec and @ellismg
It seems like we'll land on not having these classes and instead representing these "special" types with a JSON object and give the users freedom to choose the big integer library of they liking.
{
id: {value: "60c1ebb2-875e-4988-8610-efe28a600c08", type: "Guid"},
viewCount: {value: "55999333", type: "Int64"},
name: "Some entity",
price: 123.50,
isActive: true,
inStockUntil: new Date("11/05/2020");
}
So for example if the user has BigInt they can do:
c = obj.viewCount.type === 'Int64' ? BigInt(obj.viewCount.value) : obj.viewCount
Note that these Edm
objects will only be needed when users need to explicitly set Edm.Guid
and Edm.Int64
in the Service all the other supported types will be handled by the SDK and represented as native types.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you taking community feedback on the EdmGuid and EdmInt64 class types? I've been watching this closely and really like the class representation versus the object representation. The object representation could also be used, as the classes could have the proposed properties in the object which would allow the same check of the "type" property.
} | ||
|
||
async function listTables() { | ||
const tables = await serviceClient.listTables({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(sometimes it's interesting to "document" the defaults in the sample.
So for instance, is there a default sort order, that kind of thing and just place the field with it's default value, indicating it's the default. I think this is just for your review, so no big deal, but something to consider.
e9a8368
to
136a19c
Compare
} | ||
|
||
async function deleteEntity() { | ||
await serviceClient.deleteEntity("Samples", "Part1", "Row4", "*"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Jeffrey Ritcher's comment: Do we want to hide entity operations from ServiceClient and only expose from the TableClient?
No description provided.