Skip to content
This repository has been archived by the owner on Apr 13, 2019. It is now read-only.

default projections

Konstantin Sobolev edited this page Oct 14, 2017 · 1 revision

Overview

Request input/update/output projections can be specified only partially by the client (or not specified at all, in case of update/input), in which case they will be expanded to their full version by the framework.

Lets name absent or partially built projections "partial", and fully built projections "full". This document describes how and when partial projections are converted into full ones.

Expansion is performed by the projection string parser or should be explicitly performed if using projection builders (TBD). Parser creates default projections in the following situations:

  • No tags are specified for an entity type, and it has no retro tag
  • No fields are specified for a record type
  • Map or list item projection is not specified

The way they default projections are created depends on projection type.

Output projection

Output projections are expanded based on operation projection. Operation projection may mark certain fields and models as "include in default" using + flag.

For example, given the following schema

entity Person { id: Long, rec: PersonRecord }
record PersonRecord {
  name: String
  bestFriend: Person
  worstEnemy: PersonRecord
  friends: map[Long, Person]
  enemies: list[Person]
}

resource me: PersonRecord {
  read {
    outputProjection (
      +name,
      bestFriend :(+id, rec(+name)),
      worstEnemy (+name),
      friends [] :(+id, rec(+name)),
      enemies  * :(+id, rec(+name))
    )
  }
}

a simple GET request to /me will be expanded into

/me(
  name,
  bestFriend :(id,rec(name)),
  worstEnemy (name),
  friends [] :(id,rec(name)),
  enemies  * :(id,rec(name))
)

Some default projection creation rules:

  • Unspecified parameters which have default values are created based on default values
  • required parameters without default values will cause a failure (i.e. they must be specified explicitly if corresponding projection branch is requested)
  • required map keys can't be auto-expanded and will cause a failure

Input and Update projection

Partial input and update projections get completed based on operation input/update projection and provided update data. Defaults are expanded in a similar way to outut projections, but this time expansion is guided by the actual data: only tags, fields and keys present in the data will be reflected in auto-constructed request projection. Map keys from the data will be put in the projection, which means that keys required in the operation projection won't cause a failure in this case.

Partial vs full projections inside the framework

There are several ways a request is delivered to the operation implementation. Each of the following sections describe corresponding sequence of steps and request projection transformations

Local operation invocation

  • OperationRequest with full projections is constructed
    • By either parsing projection strings, with parser performing the expansion
    • Or by using projection builders, with explicit calls to create default projections
  • LocalOperationInvocation delivers request to operation implementation
    • optionally invocation is transformed using OperationFilterChains.defaultFilterChains() to perform usual request validation and response data pruning

HTTP call

  • On the wire: partial projections in the URL + data in the body
  • data is deserialized using operation input/update projection
  • partial request output projection is expanded by request parser based on operation output projection
  • partial request input/update projection is expanded by request parser based on operation input/update projection and data
  • full projections are used to construct OperationRequest instance
  • rest as in Local operation invocation

Remote operation invocation

  • OperationRequest with full projections is constructed as in Local operation invocation
  • *RemoteOperationInvocation sends HTTP request using full projections and data from the OperationRequest. Data is serialized using full input/update request projection
  • rest as in HTTP call

Notes:

  • OperationRequest always contains fully expanded projections
  • projections may be partial on the wire, to make life easier for non-native epigraph clients