Skip to content

Instantly share code, notes, and snippets.

@lmazuel
Last active June 6, 2023 23:35
Show Gist options
  • Save lmazuel/6e816fd401dcb49dd7a041c18f579af7 to your computer and use it in GitHub Desktop.
Save lmazuel/6e816fd401dcb49dd7a041c18f579af7 to your computer and use it in GitHub Desktop.
Visibility and input values

Overview

Given a visibility on a property on an attribute on a model, should this property be serialized to be sent to the server? This explains the algorithm to let SDK decide what to send or not, depending of create, update, etc.

It doesn't adress on purpose the question of SDK design (one model, more model, kwarg only, etc.), this is a page about serialization on the wire

Tagging property with visibility

This part is well defined already. See doc. Not that I'm not talking about HTTP verbs yet at this point, just semantic intent. At a glance:

  • "read" means never send it to the server
  • "create" send it for operations with the semantic "create"
  • "update" send it for operations with the semantic "update"
  • "delete" send it for operations with the semantic "delete"

Tagging semantic on operations

Operations can be tagged explicitly for their intent using TypeSpec REST module.

  • @createOrReplacesResource is a "create" semantic
  • @createOrUpdatesResource is a "create" and "update" semantic
  • @createResource is a "create" semantic
  • @deletesResource is a "delete" semantic
  • @listsResource and @readsResource is a "read" semantic
  • @updatesResource is an "update" semantic

Using Azure Core templates, there is a 1 to 1 mapping:

  • ResourceRead implies readsResource and therefore "read" (resp. ResourceListand listsResource)
  • ResourceCreateOrUpdate implies createOrUpdatesResource and therefore "create" and "update"
  • etc.

Algorithm to decide if a field should be sent to the server

  • For operation O:
    • For a property X with visibility list L in the input model M:
      • If L is empty (no visibility information) => send
      • Else
        • If O has a REST decorator for resource:
          • If createsResource and "create" in L => send
          • If deletesResource and "delete" in L => send
          • If updatesResource and "update" in L => send
          • If createOrReplacesResource and "create" in L => send
          • If createOrUpdatesResource and "create" or "update" in L => send
        • Else (no rest decorator)
          • If O.verb is PUT or POST and "create" in L => send
          • If O.verb is PATCH or PUT and "update" in L => send
          • If O.verb is DELETE and "delete" in L => send
          • Else don't send the attribute

Notes:

  • I don't need to check "read", as if the L is non-empty, and none of the conditions on create/update/delete matches, the default is to not send the value. "read" may be valuable to decide SDK generation design (no setters, etc.), but not the discussion here.

TypeSpec example

  @doc("Updates a specified Job")
  @route("/jobs/{jobId}")
  @put
  @updatesResource(BatchJob)
  Update is RpcOperation<{

        @doc("The ID of the Job whose properties you want to update.")
        @path
        jobId: string;

        @doc("The parameters for the request.")
        @body
        parameters : BatchJob;
      },{}
  >;

This is a PUT with updatesResource decorator. Attributes with no visibility information, or that includes "update" will be sent to the server.

  @doc("Updates a specified Job")
  @route("/jobs/{jobId}")
  @put
  Update is RpcOperation<{

        @doc("The ID of the Job whose properties you want to update.")
        @path
        jobId: string;

        @doc("The parameters for the request.")
        @body
        parameters : BatchJob;
      },{}
  >;

This is a PUT with no REST decorator. Attributes with no visibility information, or that includes "create" will be sent to the server. Note that given the name of the operation, this is likely an error in the TypeSpec definition (hence the interest of the REST decorator)

@doc("Creates or updates a WidgetAnalytics")
updateAnalytics  is  Operations.ResourceCreateOrUpdate<WidgetAnalytics>;

This implies a PATCH operation with the createsOrUpdatesResource linked to both "create" and "update" semantic. Attributes with no visibility information or at least one of "create" or "update" should be sent to the server.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment