-
Notifications
You must be signed in to change notification settings - Fork 3
ERMrest Programmatic API Sketch
This outline focuses on the application-side APIs, e.g. those used by a data or model-consuming client application. It ignores internal APIs needed to help implement the behaviors.
Some idioms assumed in this sketch:
- Using nested object structures to group API behaviors rather than using longer method names.
- See the
entity
,attribute
, andattributegroup
sub-APIs on datapath.
- Using container-like objects at branching points in the object tree with common signatures.
- See
schemas
,tables
,columns
, etc. - Having
.by_position
and.by_name
member access mechanisms, etc. - Assuming idioms for checking length, iterating, etc. (Implied rather than sketched out.)
- Putting management methods on the object being managed.
- Having
.delete()
on the object itself - Having
.create()
on the container-like object where new members are being added.
- Assuming Python-like semantics for sets, lists, tuples. Might need to adapt for Javascript.
A server is bound to a URL, and session credentials are established. Catalogs can be managed or bound to then work in a particular dataset.
The catalog.datapath() method instantiates a logical data access object. Many such objects can be instantiated from the same catalog to manage different data access tasks concurrently.
- server = Server(url)
- .session.client
- .session.attributes
- .session.expires
- .login()
- .logout()
- .catalogs.create( catalog_params ) -> catalog
- .catalogs.by_id[ id ] : catalog
- catalog
- .server
- .id
- .delete()
- .introspect()... if not automatic during construction?
- .schemas.create( schema_params ) -> schema
- .schemas.by_name[ schema_name ] : schema
- other catalog management methods or properties?
- schema
- .catalog
- .name
- .delete()
- .tables.create( table_params ) -> table
- .tables.by_name[ table_name ] : table
- .annotations.create( annotation_params ) -> annotation
- .annotations.by_uri[ uri ] : annotation
- table
- .schema
- .name
- .delete()
- .columns.create ( column_params ) -> column
- .columns.by_name[ column_name ] : column
- .columns.by_position[ index ] -> column
- .keys.create( key_params ) -> key
- .keys.by_cols[ colset ] -> key
- .foreignkeys.create( fkey_params ) -> foreignkeyref
- .foreignkeys[ (from_columns, to_columns) ] : foreignkeyref
- .annotations.create( annotation_params ) -> annotation
- .annotations.by_uri[ uri ] : annotation
- column
- .table
- .name
- .type
- .delete()
- .annotations[ uri ] -> annotation
- type
- .name
- .is_array : boolean
- .base_type
- key
- .table
- .columns : colset
- .annotations.create( annotation_params ) -> annotation
- .annotations[ uri ] : annotation
- foreignkeyref
- .delete()
- .from_columns[ index ] : column
- .to_columns[ index ] : column
- .annotations.create( annotation_params ) -> annotation
- .annotations.by_uri[ uri ] : annotation
- annotation
- .subject : schema|table|column|key|foreignkeyref
- .uri
- .delete()
- .content
The objects above are relatively static, corresponding to server,
database, and model resources. The objects below are dynamic
views/wrappers over the database. A pathtable
is a table instance in
a particular query while table
is an element of the database
schema. A pathcolumn
is a column from one table instance, while a
column
is an element of the database schema.
A datapath
represents a particular dataset in an ERMrest catalog. It
combines one or more pathtable
instances linked into a relational
join and filtered by filter expressions and denoting a particular
entity context. This dataset has sub-APIs to manipulate whole
entities, attributes, or attribute-groups in the entity context of the
path.
- datapath = Datapath(table)
- .catalog
- .context : pathtable
- .filters.add(filter)
- .extend(table, context=null, link=null) -> pathtable
- .entity.get()
- .entity.post()
- .entity.put()
- .entity.delete()
- .attribute[ projection ].get()
- .attribute[ projection ].delete()
- .attributegroup[ grouping ][ projection ].get()
- .attributegroup[ grouping ][ projection ].put()
- pathtable
- .datapath
- .table
- .columns.by_name[ column_name ] : pathcolumn
- .columns.by_position[ index ] : pathcolumn
- .filters.add(filter)
- pathcolumn
- .pathtable
- .column
- .operators.by_name[ operator ](rvalue=null) -> filter
- filter
- .is_junction : boolean
- When .is_junction is true:
- .conjunction : boolean
- .subfilters[ index ] : filter
- When .is_junction is false:
- .pathcolumn
- .operator
- .rvalue
This is a variant or wrapper for datapath that discovers facets automatically and handles the linkage of facet source tables to the main context table rather than the client building up the path structure.
- facetpath = Facetpath(table)
- .catalog
- .context : pathtable
- .filters.add(filter)
- .facets.by_name[ facet_name ] : pathcolumn
- .facets.by_index[ index ] : pathcolumn
- .entity.get()
- .entity.post()
- .entity.put()
- .entity.delete()
- .attribute[ projection ].get()
- .attribute[ projection ].delete()
- .attributegroup[ grouping ][ projection ].get()
- .attributegroup[ grouping ][ projection ].put()