Projects
Projects belong to an organization
and are rooted in the corresponding /v1/projects/{org_label}
path. The purposes of projects are:
- Group and categorize sub-resources.
- Define settings that apply for operations on all sub-resources.
- Provide isolation from resources inside other projects. This behavior can be changed by defining resolvers
Access to resources in the system depends on the access control list set for them. A caller may need to prove its identity by means of an access token passed in the Authorization
header (Authorization: Bearer {token}
). Please visit Authentication to learn more about retrieving access tokens.
When creating projects, the caller must have projects/create
permissions on the current path of the project or the ancestor paths.
When updating projects, the caller must have projects/write
permissions on the current path of the project or the ancestor paths.
When reading projects, the caller must have projects/read
permissions on the current path of the project or the ancestor paths.
Project payload
{
"description": "{description}",
"base": "{base}",
"vocab": "{vocab}",
"apiMappings": [
{
"prefix": "{prefix}",
"namespace": "{namespace}"
},
...
]
}
where…
{description}
: String - an optional description for this project.{base}
: IRI - is going to be used as a curie in the generation of the@id
children resources. E.g.: Let base behttp://example.com/
. When a resource is created and no@id
is present in the payload, the platform will generate an @id which will look likehttp://example.com/{UUID}
. This field is optional and will default to{{base}}/v1/resources/{org_label}/{project_label}/_/
.{vocab}
: IRI - is going to be used as a curie prefix for all unqualified predicates in children resources. E.g. if the vocab is set tohttps://schema.org/
, when a field a resource is created and a fieldname
is present in the payload, it will be expanded tohttp://schema.org/name
by the system during indexing and fetch operations. This field is optional and will default to{{base}}/v1/vocabs/{org_label}/{project_label}/
.{apiMappings}
: Json object - provides a convinient way to deal with URIs when performing operations on a sub-resource. This field is optional.
API Mappings
The apiMappings
Json object array maps each prefix
to its namespace
so that curies on children endpoints can be used.
Having the following apiMappings
:
{
"apiMappings": [
{
"prefix": "{prefix}",
"namespace": "{namespace}"
},
{ ... }
]
}
where…
{prefix}
: String - the left hand side of a curie. It has certain constraints.{namespace}
: IRI - the right hand side of a curie. It has certain constraints (irelative-ref).
Let’s see an example:
json
{
"apiMappings": [
{
"prefix": "person",
"namespace": "http://example.com/some/person"
},
{
"prefix": "schemas",
"namespace": "https://bluebrainnexus.io/schemas/"
}
]
}
The previous payload allows us to create a schema using the following endpoints:
/v1/schemas/{org_label}/{project_label}/person
. The@id
of the resulting schema will behttp://example.com/some/person
/v1/schemas/{org_label}/{project_label}/schema:other
. The@id
of the resulting schema will behttps://bluebrainnexus.io/schemas/other
Create a project
PUT /v1/projects/{org_label}/{label}
{...}
…where {label}
is the user friendly name assigned to this project. The semantics of the label
should be consistent with the type of data provided by its sub-resources, since it’ll be a part of the sub-resources’ URI.
Example
- Request
-
curl -XPUT -H "Content-Type: application/json" "https://nexus.example.com/v1/projects/myorg/myproject" -d \ '{ "description": "example project creation", "base": "https://nexus.example.com/v1/projects/myorg/myproject/", "vocab": "https://schema.org/", "apiMappings": [ { "prefix": "person", "namespace": "http://example.com/some/person" }, { "prefix": "schemas", "namespace": "https://bluebrain.github.io/nexus/schemas/" }, { "prefix": "ex", "namespace": "http://example.com/" } ] }'
- Payload
-
{ "description": "example project creation", "base": "https://nexus.example.com/v1/myorg/myproject/", "vocab": "https://schema.org/", "apiMappings": [ { "prefix": "person", "namespace": "http://example.com/some/person" }, { "prefix": "schemas", "namespace": "https://bluebrain.github.io/nexus/schemas/" }, { "prefix": "ex", "namespace": "http://example.com/" } ] }
- Response
-
{ "@context": [ "https://bluebrain.github.io/nexus/contexts/resource.json", "https://bluebrain.github.io/nexus/contexts/admin.json" ], "@id": "https://nexus.example.com/v1/projects/myorg/myproject", "@type": "Project", "_rev": 1, "_deprecated": false, "_createdAt": "2018-09-18T09:58:00.801Z", "_createdBy": "https://nexus.example.com/v1/realms/myrealm/users/john", "_updatedAt": "2018-09-18T09:58:00.801Z", "_updatedBy": "https://nexus.example.com/v1/realms/myrealm/users/john" }
Update a project
This operation overrides the payload.
In order to ensure a client does not perform any changes to a project without having had seen the previous revision of the project, the last revision needs to be passed as a query parameter.
PUT /v1/projects/{org_label}/{label}?rev={previous_rev}
{...}
… where
{previous_rev}
: Number - the last known revision for the organization.{label}
: String - the user friendly name that identifies this project.
Example
- Request
-
curl -XPUT -H "Content-Type: application/json" "https://nexus.example.com/v1/projects/myorg/myproject?rev=1" -d \ '{ "description": "example project creation", "base": "https://nexus.example.com/v1/myorg/myproject/", "vocab": "https://schema.org/", "apiMappings": [ { "prefix": "person", "namespace": "http://example.com/some/person" }, { "prefix": "schemas", "namespace": "https://bluebrain.github.io/nexus/schemas/" }, { "prefix": "ex", "namespace": "http://example.com/" } ] }'
- Payload
-
{ "description": "example project creation", "base": "https://nexus.example.com/v1/myorg/myproject/", "vocab": "https://schema.org/", "apiMappings": [ { "prefix": "person", "namespace": "http://example.com/some/person" }, { "prefix": "schemas", "namespace": "https://bluebrain.github.io/nexus/schemas/" }, { "prefix": "ex", "namespace": "http://example.com/" } ] }
- Response
-
{ "@context": [ "https://bluebrain.github.io/nexus/contexts/resource.json", "https://bluebrain.github.io/nexus/contexts/admin.json" ], "@id": "https://nexus.example.com/v1/projects/myorg/myproject", "@type": "Project", "_rev": 2, "_deprecated": false, "_createdAt": "2018-09-18T09:58:00.801Z", "_createdBy": "https://nexus.example.com/v1/realms/myrealm/users/john", "_updatedAt": "2018-09-18T09:58:00.801Z", "_updatedBy": "https://nexus.example.com/v1/realms/myrealm/users/john" }
Deprecate a project
Locks the project, so no further operations can be performed on it or on the children resources.
Deprecating a project is considered to be an update as well.
DELETE /v1/projects/{org_label}/{label}?rev={previous_rev}
… where
{previous_rev}
: Number - the last known revision for the organization.{label}
: String - the user friendly name that identifies this project.
Example
- Request
-
curl -XDELETE "https://nexus.example.com/v1/projects/myorg/myproject?rev=3"
- Response
-
{ "@context": [ "https://bluebrain.github.io/nexus/contexts/resource.json", "https://bluebrain.github.io/nexus/contexts/admin.json" ], "@id": "https://nexus.example.com/v1/projects/myorg/myproject", "@type": "Project", "_rev": 4, "_deprecated": true, "_createdAt": "2018-09-18T09:58:00.801Z", "_createdBy": "https://nexus.example.com/v1/realms/myrealm/users/john", "_updatedAt": "2018-09-18T10:30:00.801Z", "_updatedBy": "https://nexus.example.com/v1/realms/myrealm/users/john" }
Fetch a project (current version)
GET /v1/projects/{org_label}/{label}
…where {label}
is the user friendly name that identifies this project.
Example
- Request
-
curl "https://nexus.example.com/v1/projects/myorg/myproject"
- Response
-
{ "@context": [ "https://bluebrain.github.io/nexus/contexts/resource.json", "https://bluebrain.github.io/nexus/contexts/admin.json" ], "@id": "https://nexus.example.com/v1/projects/myorg/myproject", "@type": "Project", "base": "https://nexus.example.com/v1/myorg/myproject/", "vocab": "https://schema.org/", "apiMappings": [ { "prefix": "person", "namespace": "http://example.com/some/person" }, { "prefix": "schemas", "namespace": "https://bluebrain.github.io/nexus/schemas/" }, { "prefix": "ex", "namespace": "http://example.com/" } ], "_label": "myproject", "_organizationLabel": "myorg", "_organizationUuid": "bc0eba71-2a7f-40e8-ac90-5c97fc6f37d7", "_uuid": "e622745d-5eea-4dc5-8318-58a3dd4101ff", "_rev": 4, "_deprecated": true, "_createdAt": "2018-09-18T09:58:00.801Z", "_createdBy": "https://nexus.example.com/v1/realms/myrealm/users/john", "_updatedAt": "2018-09-18T10:30:00.801Z", "_updatedBy": "https://nexus.example.com/v1/realms/myrealm/users/john" }
Fetch a project (specific version)
GET /v1/projects/{org_label}/{label}?rev={rev}
…where
{label}
: String - the user friendly name that identifies this project.{rev}
: Number - the revision of the project to be retrieved.
Example
- Request
-
curl "https://nexus.example.com/v1/projects/myorg/myproject?rev=4"
- Response
-
{ "@context": [ "https://bluebrain.github.io/nexus/contexts/resource.json", "https://bluebrain.github.io/nexus/contexts/admin.json" ], "@id": "https://nexus.example.com/v1/projects/myorg/myproject", "@type": "Project", "base": "https://nexus.example.com/v1/myorg/myproject/", "vocab": "https://schema.org/", "apiMappings": [ { "prefix": "person", "namespace": "http://example.com/some/person" }, { "prefix": "schemas", "namespace": "https://bluebrain.github.io/nexus/schemas/" }, { "prefix": "ex", "namespace": "http://example.com/" } ], "_label": "myproject", "_organizationLabel": "myorg", "_organizationUuid": "bc0eba71-2a7f-40e8-ac90-5c97fc6f37d7", "_uuid": "e622745d-5eea-4dc5-8318-58a3dd4101ff", "_rev": 4, "_deprecated": true, "_createdAt": "2018-09-18T09:58:00.801Z", "_createdBy": "https://nexus.example.com/v1/realms/myrealm/users/john", "_updatedAt": "2018-09-18T10:30:00.801Z", "_updatedBy": "https://nexus.example.com/v1/realms/myrealm/users/john" }
List projects
GET /v1/projects?from={from}&size={size}&deprecated={deprecated}&rev={rev}&type={type}&createdBy={createdBy}&updatedBy={updatedBy}&label=label
where…
{from}
: Number - is the parameter that describes the offset for the current query; defaults to0
{size}
: Number - is the parameter that limits the number of results; defaults to20
{deprecated}
: Boolean - can be used to filter the resulting projects based on their deprecation status{rev}
: Number - can be used to filter the resulting projects based on their revision value{type}
: Iri - can be used to filter the resulting projects based on their@type
value. This parameter can appear multiple times, filtering further the@type
value.{createdBy}
: Iri - can be used to filter the resulting projects based on their creator{updatedBy}
: Iri - can be used to filter the resulting projects based on the person which performed the last update{label}
: String - can be used to filter the resulting projects based on its label. E.g.:label=my
will match any project’s label that contains the stringmy
.label='my'
will match any project where label is equal tomy
.
Example
- Request
-
curl "https://nexus.example.com/v1/projects"
- Response
-
{ "@context": [ "https://bluebrain.github.io/nexus/contexts/admin.json", "https://bluebrain.github.io/nexus/contexts/search.json", "https://bluebrain.github.io/nexus/contexts/resource.json" ], "_total": 1, "_results": [ { "@id": "https://nexus.example.com/v1/projects/myorg/myproject", "@type": "Project", "base": "http://nexus.example.com/", "vocab": "http://schema.org/", "apiMappings": [ { "namespace": "http://schema.org/", "prefix": "schema" } ], "_uuid": "e622745d-5eea-4dc5-8318-58a3dd4101ff", "_label": "myproject", "_organizationUuid": "bc0eba71-2a7f-40e8-ac90-5c97fc6f37d7", "_organizationLabel": "myorg", "_rev": 4, "_deprecated": true, "_createdAt": "2018-09-18T09:58:00.801Z", "_createdBy": "https://nexus.example.com/v1/realms/myrealm/users/john", "_updatedAt": "2018-09-18T10:30:00.801Z", "_updatedBy": "https://nexus.example.com/v1/realms/myrealm/users/john" } ] }
List projects belonging to an organization
GET /v1/projects/{org_label}?from={from}&size={size}&deprecated={deprecated}&rev={rev}&type={type}&createdBy={createdBy}&updatedBy={updatedBy}&label=label
where…
{from}
: Number - is the parameter that describes the offset for the current query; defaults to0
{size}
: Number - is the parameter that limits the number of results; defaults to20
{deprecated}
: Boolean - can be used to filter the resulting projects based on their deprecation status{rev}
: Number - can be used to filter the resulting projects based on their revision value{type}
: Iri - can be used to filter the resulting projects based on their@type
value. This parameter can appear multiple times, filtering further the@type
value.{createdBy}
: Iri - can be used to filter the resulting projects based on their creator{updatedBy}
: Iri - can be used to filter the resulting projects based on the person which performed the last update{label}
: String - can be used to filter the resulting projects based on its label. E.g.:label=my
will match any project’s label that contains the stringmy
.
Example
- Request
-
curl "https://nexus.example.com/v1/projects/myorg"
- Response
-
{ "@context": [ "https://bluebrain.github.io/nexus/contexts/admin.json", "https://bluebrain.github.io/nexus/contexts/search.json", "https://bluebrain.github.io/nexus/contexts/resource.json" ], "_total": 1, "_results": [ { "@id": "https://nexus.example.com/v1/projects/myorg/myproject", "@type": "Project", "base": "http://nexus.example.com/", "vocab": "http://schema.org/", "apiMappings": [ { "namespace": "http://schema.org/", "prefix": "schema" } ], "_uuid": "e622745d-5eea-4dc5-8318-58a3dd4101ff", "_label": "myproject", "_organizationUuid": "bc0eba71-2a7f-40e8-ac90-5c97fc6f37d7", "_organizationLabel": "myorg", "_rev": 4, "_deprecated": true, "_createdAt": "2018-09-18T09:58:00.801Z", "_createdBy": "https://nexus.example.com/v1/realms/myrealm/users/john", "_updatedAt": "2018-09-18T10:30:00.801Z", "_updatedBy": "https://nexus.example.com/v1/realms/myrealm/users/john" } ] }
Project Server Sent Events
This endpoint allows clients to receive automatic updates from the projects in a streaming fashion.
GET /v1/projects/events
where Last-Event-Id
is an optional HTTP Header that identifies the last consumed project event. It can be used for cases when a client does not want to retrieve the whole event stream, but to start after a specific event.
The response contains a series of project events, represented in the following way
data:{payload}
event:{type}
id:{id}
where…
{payload}
: Json - is the actual payload of the current project{type}
: String - is a type identifier for the current project. Possible types are: ProjectCreated, ProjectUpdated and ProjectDeprecated{id}
: String - is the identifier of the project event. It can be used in theLast-Event-Id
HTTP Header
Example
- Request
-
curl "https://nexus.example.com/v1/projects/events"
- Response
-
data:{"@context":["https://bluebrain.github.io/nexus/contexts/admin.json","https://bluebrain.github.io/nexus/contexts/resource.json"],"@type":"ProjectCreated","description":"rel07bd3x7ux7xy/3g2tp5jdtj2bii7 project","base":"http://nexus.example.com/v1/resources/rel07bd3x7ux7xy/3g2tp5jdtj2bii7/_/","vocab":"http://nexus.example.com/v1/vocabs/rel07bd3x7ux7xy/3g2tp5jdtj2bii7/","apiMappings":[{"prefix":"nxv","namespace":"https://bbp-nexus.epfl.ch/vocabs/nexus/core/terms/v0.1.0/"},{"prefix":"person","namespace":"https://shapes-registry.org/commons/person"}],"_uuid":"0ccd8bb7-e2d6-468b-bf35-2d01f3ddaedf","_label":"3g2tp5jdtj2bii7","_organizationUuid":"cfd51482-294f-4f52-be78-8edce0775c42","_organizationLabel":"rel07bd3x7ux7xy","_rev":1,"_instant":"2019-06-14T11:59:14.684Z","_subject":"http://nexus.example.com/v1/realms/nexusdev/users/test"} event:ProjectCreated id:d47715c0-8e9b-11e9-81dd-338cb949d9cb data:{"@context":["https://bluebrain.github.io/nexus/contexts/admin.json","https://bluebrain.github.io/nexus/contexts/resource.json"],"@type":"ProjectUpdated","description":"rel07bd3x7ux7xy/3g2tp5jdtj2bii7 project update 1","base":"http://nexus.example.com/v1/tmynbseodckawgit/","vocab":"http://nexus.example.com/v1/iwspaxkdbrpfsbni/","apiMappings":[{"prefix":"nxv","namespace":"https://bbp-nexus.epfl.ch/vocabs/nexus/core/terms/v0.1.0/"},{"prefix":"person","namespace":"https://shapes-registry.org/commons/person"},{"prefix":"xsd","namespace":"http://www.w3.org/2001/XMLSchema#"}],"_uuid":"0ccd8bb7-e2d6-468b-bf35-2d01f3ddaedf","_label":"3g2tp5jdtj2bii7","_rev":2,"_instant":"2019-06-14T11:59:19.544Z","_subject":"http://nexus.example.com/v1/realms/nexusdev/users/test"} event:ProjectUpdated id:d7602bf0-8e9b-11e9-81dd-338cb949d9cb data:{"@context":["https://bluebrain.github.io/nexus/contexts/admin.json","https://bluebrain.github.io/nexus/contexts/resource.json"],"@type":"ProjectUpdated","description":"rel07bd3x7ux7xy/3g2tp5jdtj2bii7 project update 2","base":"http://nexus.example.com/v1/wwpeuyhtqbsesfxl/","vocab":"http://nexus.example.com/v1/xqbfndagddjerwwc/","apiMappings":[{"prefix":"nxv","namespace":"https://bbp-nexus.epfl.ch/vocabs/nexus/core/terms/v0.1.0/"},{"prefix":"person","namespace":"https://shapes-registry.org/commons/person"},{"prefix":"xsd","namespace":"http://www.w3.org/2001/XMLSchema#"}],"_uuid":"0ccd8bb7-e2d6-468b-bf35-2d01f3ddaedf","_label":"3g2tp5jdtj2bii7","_rev":3,"_instant":"2019-06-14T11:59:20.094Z","_subject":"http://nexus.example.com/v1/realms/nexusdev/users/test"} event:ProjectUpdated id:d7b66240-8e9b-11e9-81dd-338cb949d9cb data:{"@context":["https://bluebrain.github.io/nexus/contexts/admin.json","https://bluebrain.github.io/nexus/contexts/resource.json"],"@type":"ProjectDeprecated","_uuid":"0ccd8bb7-e2d6-468b-bf35-2d01f3ddaedf","_rev":4,"_instant":"2019-06-14T11:59:23.722Z","_subject":"http://nexus.example.com/v1/realms/nexusdev/users/test"} event:ProjectDeprecated id:d9de7260-8e9b-11e9-81dd-338cb949d9cb