Overview
This document describes the GraphQL-API provided by the Application Layer. The GraphQL API is for developers who want to integrate the Application Layer into their application and for administrators who want to script interactions with the Application Layer Server.
The Application Layer’s GraphQL API provides access to almost all services and resources of the Application Layer via queries/mutations.
To use the GraphQL API, your application will make a POST HTTP request - which contains the GraphQL’s queries/mutations - to the GraphQL’s endpoint http(s)://hostname:port/nscalealinst1/graphql
, and parse the response.
The response format is JSON. Your queries/mutations will have the same names as the names of the service’s methods in the Application Layer. Mutation’s names have as prefix the name of their root service.
GraphQL is schema based, and has a strong type system, Because of that, it is possible to introspect the schema. With the schema introspection, GraphQL has many advantages. With schema introspection you can use a various number of tools for the development, such as tools for testing/introspection and for schema visualization. Application Layer comes with two such tools, namely GraphQL-Playground
and GraphQL-Voyager
. More details about these tools will be mentioned later in this document.
1. Introduction
Accessing GraphQL API is performed via HTTP. GraphQL API uses only one HTTP method: POST request method. Other than REST API, GraphQL has only one endpoint, which is: http(s)://hostname:port/nscalealinst1/graphql
Clients can request data or performs internal server operations/changes by sending queries or mutations to the GraphQL endpoint through POST requests. In GraphQL there are three operations: query
, mutation
, subscription
. The Application Layer GraphQL API supports only two of these operation: query and mutation.
With query data can be requested/retrieved, and with mutation changes/modifications can be made to the server/data.
Say that we want to request some information about the common setting from the configuration service in the Application Layer, so our GraphQL query will look like the following:
query {
configurationService {
commonSetting {
deletionPolicy
lastModified
idleSessionLifeTime
}
}
}
This GraphQL query should be sent within a POST request in the body of the request. A GraphQL POST request of this query should look like the following:
POST /nscalealinst1/graphql HTTP/1.1
Host: hostname:port
Content-Type: application/json;charset=UTF-8
Authorization: Basic YWRtaW46YWRtaW4=
Accept: application/json;charset=UTF-8
{"operationName":null,"variables":{},"query":"{\n configurationService {\n commonSetting {\n deletionPolicy\n lastModified\n idleSessionLifeTime\n }\n }\n}\n"}
It’s important to include the authorization information in the headers of request. The authorization information consist of the nscale user name and password, decoded to Base64 (aka: Basic HTTP authentication).
The Application-Layer GraphQL-API supports only the JSON representation format.
Changing/Uploading binary data is possible since nscale Applicationlayer 8.3. |
2. GraphQL Endpoint, Header and Parameter
2.1. Endpoint URL
The main and only endpoint URL for a Application-Layer GraphQL API has the following structure:
http(s)://hostname:port/nscalealinst1/graphql
The Application Layer only uses a self-signed certificate by default. You can replace this server certificate with a digitally signed certificate by a certificate authority (CA).
The self-signed certificate can be downloaded at http(s)://hostname:port/server.certificate
Number | Description |
---|---|
8080 |
plain HTTP port |
8443 |
secure HTTPS port |
The logical application layer instance is part of the URL. Your application should make this entry configurable.
Name | Description |
---|---|
nscalealinst1 |
The default application-layer instance name (can be changed) |
[any-name] |
Secondary logical instance name |
In GraphQL API there are several Application Layer services available. Here are the available services in GraphQL:
Name | Description |
---|---|
administrative |
administrative functionality: administrative access on resources, e.g. to copy or move resources from one document area to another |
authentication |
authentication functionality: session and authentication infos |
authoritymanagement |
authority management functionality: roles |
collaboration |
collaboration functionality: groups, teamspaces and calendars |
configuration |
configuration functionality: dictionary, layouts, property definitions, value sets |
masterdata |
masterdata functionality: external data |
monitoring |
monitoring functionality: monitoring data, invoke generic |
messaging |
messaging functionality: subscribe resources and workflow, read messages |
repository |
repository functionality: folder, link and document management |
usermanagement |
user management functionality: principals, org. entities, groups and users. |
workflow |
workflow functionality: processes and taks |
The document graphql_schema.graphql
contains the full GraphQL schema.
2.2. Common Request Header and Query Parameter
The following table describes headers that can be used by GraphQL requests.
Header | Description |
---|---|
Authorization |
The information required for request authentication |
Accept |
Media type that is acceptable for the response (content negotiation). |
Content-Type |
Media type of the body of the request. |
Header | Description |
---|---|
appid |
The client application id of the client. If no appid is given, the client requires the 'nscale SDK' license. |
autoclose=true |
The application cannot use the session cookie. Close session after request. |
clientversion |
The client application version. |
2.3. Response Header
The following table describes response headers that are common to GraphQL responses.
Header | Description |
---|---|
Content-Length |
Length of the message (without the headers) according to RFC 2616 |
Content-Type |
The content type of the resource in case the request content in the body |
3. GraphQL Tools
3.1. GraphQL-Playground
GraphQL-Playground is a graphical, interactive, in-browser GraphQL IDE that helps you during the development. With GraphQL-Playground you can send queries/mutations and get responses live from the Application Layer server.
GraphQL-Playground supports auto-completion, which means that you will be able to explore the schema of GraphQL API and with that you will be able to explore the services of the Application Layer, and their methods in such a way that it will be almost self-explaining and self-documenting. It will make it super easy to understand how to use the methods of the services in the Application Layer and which result to expect.
GraphQL-Playground also supports error highlighting, so that you will always be sure that you are writing the correct working queries/mutations - for your Applications - that deliver the wished and expected results every time!
cURL input can be generated with GraphQL-Playground so that your queries in Playground can be directly executed with cURL. All what you need to do is to click on COPY CURL
on Playground tool, and the query/mutation on Playground will be included on a generated cURL input that will be saved on the system clipboard.
3.2. GraphQL-Voyager
GraphQL-Voyager is used to visualize the GraphQL schema in a way that is similar to UML Diagrams. This helps you even more understanding how the schema, and the underlying structure of the Application Layer is built.
GraphQL-Voyager let you filter Application Layer data types in such a manner that you can get a specific parts of the whole graph and thus reduce the complexity of the graph.
Layout
4. GraphQL Examples
4.1. With cURL
First try to access the application layer via the cURL command line tool.
Here is an example session:
curl -v --basic -u admin:admin
-H "Content-Type:application/json"
-d "{\"query\":\"query {\n configurationService {\n commonSetting {\n
deletionPolicy\n lastModified\n idleSessionLifeTime\n
}\n }\n}\"}"
http://localhost:8080/nscalealinst1/graphql
POST /nscalealinst1/graphql HTTP/1.1
Host: localhost:8080
Authorization: Basic YWRtaW46YWRtaW4=
User-Agent: curl/7.55.1
Accept: */*
Content-Type:application/json
Content-Length: 150
Answer from Application Layer:
HTTP/1.1 200
Set-Cookie: JSESSIONID=BE70947D157C8B6E9A7581507A15DBAF; Path=/nscalealinst1; HttpOnly
Content-Type: application/json;charset=UTF-8
Content-Length: 159
Date: Mon, 15 Feb 2021 17:13:13 GMT
{"data":{"configurationService":{"commonSetting":{"deletionPolicy":"DeletePhysical","lastModified":"2021-02-08T15:28:33.942+01:00","idleSessionLifeTime":60}}}}
Programming
5. GraphQL Client
Let’s write GraphQL queries and mutations for a typical client for the GraphQL-API. The queries and mutations will be written with GraphQL-Playground. Note that the user permissions will be considered during the query/mutation executions.
5.1. Authentication Service
5.1.1. Login
The standard HTTP authentication mechanism is used by GraphQL:
-
Basic
-
NTLM
-
Negotiate (Kerberos or NTMLv2)
-
OpenID Connect (ADFS)
Additional authentication schemas:
-
Implicit (can be used for impersonation)
-
AuthID (ID/secure-card based login)
-
KNM (Kyocera Network Manager )
-
SAML (planned)
The server uses a session cookie. The client should use this cookie for following requests.
GraphQL-Playground auto completion
It will be so easy to write the query with the auto-completion features that comes with GraphQL-Playground.
Auto-completion is performed by clicking the following key combination: |
Click to see query used in the image
query sessionInfo {
authenticationService {
login {
sessionPrincipalId
sessionPrincipal {
userName
domainName
}
sessionGroupIds
sessionDefaultPositionId
sessionPositionIds
serverVersion
}
}
}
The above GraphQL query retrieves additional information of the session access rights (more fields can be selected!).
5.1.2. Logout
mutation sessionLogout {
AuthenticationService_logout
}
This mutation will close the server session and the HTTP session for the GraphQL adapter.
Warning
just disconnecting the HTTP connection will leave an open session in the server. |
5.2. Configuration Service
5.2.1. retrieve Common Settings
Let’s say we want to get some common setting informations from Application Layer server. For some reasons we want only the following informations: deletion policy
, idle session lifetime (in minutes)
and jdbc batch size
. We would write the following query with GraphQL-Playground (see figure 4).
Click to see query used in the image
query getCommonSettings {
configurationService {
commonSetting {
deletionPolicy
idleSessionLifeTime
jdbcBatchSize
}
}
}
5.2.2. update Common Settings
To make a change to data or settings in the Application Layer, we can write a GraphQL-Mutation to perform the wished changes. For instance, we can change the following common settings: idleSessionLifeTime
, deletionPolicy
, createPreviews
with the following mutation:
Click to see query used in the image
mutation changeCommonSettings {
ConfigurationService_update (
configuration: {
CommonSetting: {
deletionPolicy: DeletePhysical
idleSessionLifeTime: 90
createPreviews: true
}
}
)
}
graphql input & input fields
to fill graphql input, you should write |
Other configuration objects can be updated the same way as CommonSetting
. Note that CommonSetting is a singletone configuration object, that means it has no identifier and there is only one such configuration object that exists in the whole Application Layer. Other configuration objects may have identifiers, so be aware!
5.2.3. retrieve Document Area settings
In the case that we want to get specific informations about the document area DA
, like defaultContentType
, expirationRulesDateInheritancePolicy
,lastModified
and appendNotePolicy
we would write the following GraphQL query:
Click to see query used in the image
query getDocAreaInfos {
configurationService {
documentArea (docAreaName:"DA") {
defaultContentType
expirationRulesDateInheritancePolicy
lastModified
notesSetting {
appendNotePolicy
}
}
}
}
selecting nested fields
note that |
If we want to get all Document Areas, we would write a query that use the Configuration Service operation documentAreas
and we could select any wished fields (just like the query above).
5.2.4. create a Document Area
To create a new document area with some initial configuration, you will need to write a mutation that looks like the following:
Click to see query used in the image
mutation createNewDocArea {
ConfigurationService_add (
configuration: {
DocumentArea: {
areaName: "GraphQL_DocArea"
displayNameId: "graphql docarea"
descriptionId: "created from graphql!"
deletionPolicy: DeleteStateAware
notesSetting: {
appendNotePolicy: Top
}
}
}
)
}
identifiers of the configuration objects
note that some configuration objects have identifiers, and cannot be access or created without these identifiers. The |
5.2.5. update a Document Area
To update a Document Area we would write a mutation that use the operation ConfigurationService_update
, like the following:
Click to see query used in the image
mutation updateDocArea {
ConfigurationService_update(
configuration: {
DocumentArea: {
areaName: "DA"
versioningFolders: true
associatedContentTypes: [
"application/pdf",
"application/msoutlook"
]
}
}
)
}
updating lists and arrays inside a configuration object
when updating lists, sets or arrays inside a configuration object, the list won’t be merged with the new values! The updated list will have only the new values, so be very careful when updating big lists! When you have big lists, you would programmatically save them in variables and then add the new elements to them and then make the update. To update a list and make it empty, you can do this by writing |
5.2.6. delete a Document Area
To delete a document area, you will need only one field to write, namely the identifier field areaName
:
Click to see query used in the image
mutation deleteDocArea {
ConfigurationService_delete (
configuration: {
DocumentArea: {
areaName: "GraphQL_DocArea"
}
}
)
}
5.3. User Management Service
5.3.1. all users of a domain
To show all users of the default nscale domain, and some of their informations, like login
name and principalId
, you would write a query that looks like the following:
Click to see query used in the image
query domainUsers {
userManagementService {
allDomainUsers (domainName: "nscale") {
login
active
principalId
commonName
lastModified
}
}
}
graphql alias
you can rename client wise any field by using graphql-alias. To use them, write any chosen name and then add |
5.3.2. create new user
For creating a new user, we write a mutation that use the user management service’s operation createUser(user:UserInput, password:String)
. Note that a user has as identifier (name, domainName)
or (name, domainName, principalId)
, so make sure to write one of them when creating a user.
Click to see query used in the image
mutation createUser {
UserManagementService_createUser(
user: {
name: "docu_user"
domainName: "nscale"
description: "for the documentation only!"
}
password: "docu_cool!"
)
{
name
principalId
}
}
mutation return value
not all mutations are of type void, some mutation return objects as a result of the execution and this can be useful in many cases, such as getting the generated |
5.4. Repository Service
5.4.1. root folder of a Document Area
To start on a document area you must retrieve the root entry point (resource key).
Click to see query used in the image
query rootFolder {
repositoryService {
rootFolderWithProps(
documentAreaName: "DA"
propNames: [
{ IndexingPropertyName: { name: "displayname", areaName: "DA" } }
{ IndexingPropertyName: { name: "creationdate", areaName: "DA" } }
]
) {
resourceKey
properties {
propertyName {
name
}
value
}
}
}
}
5.4.2. children of a folder
To display the child elements of a folder, you must retrieve the possible children. With SearchControl
you can specify, which properties should be returned and how they should be ordered and which condition should be used. With filter
, you can even write a condition, in this example the condition is to return only the files that has the extension of a MS-Word documents. Note that GraphQL-alias were used in the result. Note that there is a comment inside the field sortOrder
. Comments can be written inside GraphQL-Queries or Mutations, and they begin with the character #
.
query folderChildren {
repositoryService {
children(
folderKey: "DA$NOTSET$2$1$NOTSET"
searchControl: {
propNames: [
{ IndexingPropertyName: { name: "displayname", areaName: "DA" } }
{ IndexingPropertyName: { name: "objectclass", areaName: "DA" } }
{ IndexingPropertyName: { name: "creationdate", areaName: "DA" } }
]
paging: { pageNumber: 1, pageSize: 20 }
searchScope: OneLevel
sortOrder: {
# result is sorted by 'displayname', ascending
propertyName: {
IndexingPropertyName: { name: "displayname", areaName: "DA" }
}
sortOrder: ASC
}
filter: "displayname like \"*.doc*\""
}
) {
resultTable {
resourceKeys
firstElement: row(rowIndex: 0)
displayNames: column(columnIndex: 0)
objectClasses: column(columnIndex: 1)
creationDates: column(columnIndex: 2)
}
}
}
}
The result is a table with resource keys and their properties. Try to execute the above query to find out how the result table is structured. Try to use the auto-completion functionality when writing your query.
5.4.3. search for elements
Searching in folders is analog to childern. The only difference is that searching method has many variants, such as with fulltext query
, or with nql query
instead of SearchControl
.
5.4.4. modify properties
To modify element properties, we write a mutation that does several tasks:
-
locking the resource
-
modifying resource’s properties
-
unlocking the resource
So if you want to modify the property value of displayname
, you would write the following mutation:
mutation modifyProperties {
RepositoryService_lock(resourceKey: "DA$NOTSET$309$2$NOTSET")
RepositoryService_updateProperties(
resourceKey: "DA$NOTSET$309$2$NOTSET"
props: [
{
propertyName: {
IndexingPropertyName: { name: "displayname", areaName: "DA" }
}
value: "new_docu"
}
]
)
RepositoryService_unlock(resourceKey:"DA$NOTSET$309$2$NOTSET")
}
If everything worked properly, void operations should return true
, and the response would be something like this:
{
"data": {
"RepositoryService_lock": true,
"RepositoryService_updateProperties": true,
"RepositoryService_unlock": true
}
}
mutation execution
Operations inside a graphql-mutation are executed in a serial way. That guarantied that the operation are executed in the wished order and that makes a lot of sense in most of the cases, like the above example. In the other hand, operations inside queries are not executed serially. |
5.5. Authority Management Service
5.5.1. all permissions of a role
To get all permissions of a specific role, the role name and area name are required. With the graphql operation getPermissions
a list [Permissions]
of all types of permissions is returned. Since the type Permissions
is a graphql interface, a special graphql syntax is required to select the result. The interface Permissions has the following subtypes/implementations:
-
SystemAdminPermissions
-
UserAdminPermissions
-
DocAreaAdminPermissions
-
DocumentPermissions
-
FolderPermissions
-
LinkPermissions
-
MasterdataPermissions
-
WorkflowPermissions
-
BusinessProcessPermissions
So the graphql query would look like the following:
query getRolePermissions {
authorityManagementService {
allPermissions(roleNames: [{ areaName: "*", name: "SystemAdmin" }]) {
...on DocAreaAdminPermissions {
__typename
docAreaAdmin
docAreaName
layoutAdmin
monitoringAdmin
physicallyDelete
}
...on UserAdminPermissions {
__typename
auditAdmin
domainAdmin
domainName
}
...on SystemAdminPermissions {
__typename
configurationAdmin
monitoringAdmin
revisionAdmin
}
# ...on MasterdataPermissions {...}
}
}
}
syntax for interfaces
when retrieving data from an operation that has an interface type as return type, selecting the data should be done with the special graphql syntax |
From the above query we can see that the area name is not specific, and is a star *
. This indicates that the role was a global role and applies to all document areas in the ApplicationLayer instance.
5.5.2. update permissions
To update permissions of a role, use the mutation AuthorityManagementService_updatePermissions
. It should be noted, that some permissions have identifiers, so these identifiers should be always given, whenever we want to update or remove a permission.
The following query illustrates how updating permissions works:
mutation updateRolePermissions {
AuthorityManagementService_updatePermissions (
roleName: { areaName:"*", name:"SystemAdmin" }
permissions:[
{
SystemAdminPermissions: {
monitoringAdmin: false
revisionAdmin: true
}
}
{
DocAreaAdminPermissions: {
docAreaName: "DA"
layoutAdmin: false
physicallyDelete: false
}
}
]
)
}
The mutation updatePermissions
can be also used to add new permission to a given role. Use the mutation setPermissions
to initialize permissions for a role.
5.5.3. remove permissions
Permissions can be also removed for a given role. The identifiers of the permissions are the only required information when removing a permission for a given role. A graphql query for removing permissions should look like the following:
mutation removeRolePermissions {
AuthorityManagementService_removePermissions(
roleName: { areaName: "*", name: "SystemAdmin" }
permissions: [
{
DocAreaAdminPermissions: {
docAreaName: "DA"
}
}
]
)
}
new operations
the mutations |
5.6. Uploading Binary Files
Since graphql supports only JSON representation format, it is difficult and inefficient to upload binary files
within JSON format. In this case the binary file payload would be encoded into base64
string and will be then written
in the JSON request. The encoded base64
strings are usually very large, and are in most cases larger
than the original binary file content. It is an expensive and inefficient way to upload binary files with this
method, since you need to encode the content of the binary file client wise to base64
format, and when sending the
request, the request will be very large and the base64
encoded string should be decoded server wise. This is clearly not an optimal solution for uploading binary files with graphql.
A better and efficient solution is to create a multipart/form request and send the binary file within it. according to the GraphQL multipart request specification there should be three form-fields, which are ordered like the following:
-
operations
-
map
-
File field
The form-field operation should contain a JSON encoded object that represents the normal graphql POST request body:
{
"query": "...",
"variables": { "var_1": "value_1", ... }
}
Every variable value of a file in the operations form-field should be replaced with null
value. The form-field map
should be a JSON encoded map that describes where the files in operations are. An entry of this map is corresponding
to a file, where the key is the file multipart form-field name and the value is an array of operations paths. The
final form-field is the binary file field, where the actual binary file name is mapped to the file key from the
above-mentioned map. There could be one or many file fields, it depends on the operations that should be executed.
The following example shows how to upload a single binary file with graphql using cURL:
curl -v --basic -u admin:admin http://localhost:8080/nscalealinst1/graphql ^
-F operations="{\"query\":\"mutation upload($file: Upload, $folder: String) {
uploadFile(content: $file, folder: $folder )}\",
\"variables\":{\"file\":null,\"folder\":\"folderId\"}}" ^
-F map="{\"0\":[\"variables.file\"]}" ^
-F 0=@small_file.pdf
note how the file variable value was set to |
Multiple files could be also uploaded with this method. The following example shows how to upload multiple files with graphql using cURL:
curl -v --basic -u admin:admin http://localhost:8080/nscalealinst1/graphql ^
-F operations="{\"query\":\"mutation upload($files: [Upload], $folder: String) {
uploadFiles(contentList: $files, folder:$folder )}\",
\"variables\":{\"files\":[null,null],\"folder\":\"folderId\"}}" ^
-F map="{\"0\":[\"variables.files.0\"], \"1\":[\"variables.files.1\"]}" ^
-F 0=@small_file.pdf ^
-F 1=@big_file.docx
the operations |
After sending these requests to the server, the server should know how to handle them properly. So the server should meet the specification to be able to handle the request. ApplicationLayer knows already how to handle them.
For clients there are already many libraries that meet the specification and produce such requests. For instance,
for JavaScript
the library apollo-upload-client
could be used in combination with apollo client
.
5.6.1. File Upload with ApplicationLayer
There are new graphql operations where uploading binary files is possible. The new operations are mutations and belong to the RepositoryService and are:
createDocument (content: [Upload]!,
parentKey: String,
documentObjectclassName: ObjectclassNameInput,
properties:[PropertyInput],
archived: Boolean,
initialLock: Boolean)
createExtension (content: [Upload]!,
ownerKey: String,
type: ExtensionType,
properties: [PropertyInput])
updateContent (content: [Upload]!, resourceKey: String)
update (content: [Upload]!, resourceKey: String, props: [PropertyInput])
proceedContent (content: [Upload]!, documentKey: String)
proceed (content: [Upload]!, documentKey: String, props: [PropertyInput])
new operations
the above mutations are only available since the ApplicationLayer
version |
The following example demonstrates the correct usage of one of the new ApplicationLayer mutations:
curl -v --basic -u admin:admin http://localhost:8080/nscalealinst1/graphql ^
-F operations="{\"query\":\"mutation updateContent($file: [Upload]!,
$docKey: String!) {
RepositoryService_updateContent(content: $file,
resourceKey: $docKey)}\",
\"variables\":{\"file\":[null], \"docKey\":\"da$1$9285$2$1\"}}" ^
-F map="{\"0\":[\"variables.file.0\"]}" ^
-F 0=@one_giga.zip
The above example shows how to update the resource’s content with a single-content-item document using the new mutation updateContent
. Only one file should be uploaded to create single-content-item document.
When creating a single-content-item document with the new ApplicationLayer mutations, the variable |
Uploading multiple files to create multi-content-item document is also possible with the new ApplicationLayer mutations. The following example shows how to upload files to build a nscale multi-content-item document:
curl -u admin http://localhost:8080/nscalealinst1/graphql ^
-F operations="{\"query\":\"mutation multiItemDocument($file: [Upload]!,
$parent: String!, $objclass: ObjectclassNameInput!,
$props: [PropertyInput]){
RepositoryService_createDocument(content: $file,
parentKey: $parent,
documentObjectclassName:$objclass,
initialLock: true,
properties:$props)}\",
\"variables\":{\"file\":[null,null,null],
\"parent\":\"da$NOTSET$2$1$NOTSET\",
\"props\":[{\"propertyName\":
{\"IndexingPropertyName\": {\"name\":
\"displayname\", \"areaName\": \"da\"}},
\"value\":\"multiContentItemDoc\"}],
\"objclass\":{\"name\":\"D1\",
\"areaName\":\"da\"}}}" ^
-F map="{\"0\":[\"variables.file.0\"], \"1\":[\"variables.file.1\"],
\"2\":[\"variables.file.2\"]}" ^
-F 0=@top_secret.pdf ^
-F 1=@classified.docx ^
-F 2=@dont_readme.txt
With the above example a multi-content-item document with the name multiContentItemDoc
is created. This document has the content-type multipart/mixed
.
If all files have the same content-type, then the multi-content-item document won’t have the content-type |
Every mutation that accepts multiple files [Upload]
can create nscale single-content-item documents when uploading only one file or multi-content-item documents when uploading multiple files.
Uploading multiple files to create multiple single-content-item documents is also possible with the following brand-new ApplicationLayer Graphql mutation:
createMultipleDocuments (files: [Upload]!,
parentKey: String!,
objectclassName: ObjectclassNameInput,
properties: [PropertyInput])
The property displayname
of every created document will be automatically set to the name of the corresponding uploaded file. Other properties could be manually specified for all uploaded files, when wished. The parameter objectclassName
is also optional, and if it is not specified, the default object class will be set. This mutation is useful if we want to upload a bunch of files with only one request. This could be useful for implementing client functionalities like drag and drop files into nscale
or something similar.
It is not possible to specify the property values for each newly created document with the above mutation. Specified property values will apply to all newly created document equally, so be aware! |
5.7. Downloading Files
Like file upload, file download with graphql is not straight forward since graphql supports only JSON representation format. To make graphql supports binary file download, a workaround is implemented where the servlet context is accessed and the binary data is directly written within the servlet http response. With this approach we can perform a pure binary file download that has great performance, and this is how file download is implemented in the Application Layer graphql api.
There are two brand-new operations in the Application Layer graphql api which support file download, and are part of the repository service:
downloadDocument (resourceKey: String, itemIndex: Int): Boolean
downloadMultipleDocuments (resourceKeys: [String]): Boolean
note that the operation parameter |
With the operation downloadDocument
we can download any document inside nscale system by delivering the resource key of that resource.
If the resource is a multi content item document then we will get as a result of the download process a zip file that contains all content items of that resource. If we want only a specific content item from the multi content item document, then we should specify the index of that content item with the operation parameter itemIndex
.
The following example shows how to download a single content item document:
curl -v --basic -u admin:admin -O -J http://localhost:8080/nscalealinst1/graphql ^
-F operations="{\"query\":\"query downloadADocument($resKey: String!){
repositoryService {
downloadDocument(resourceKey: $resKey)
}
}\",
\"variables\":{\"resKey\":\"da$NOTSET$154$2$NOTSET\"}}"
to download file using |
Downloading a multi content item document is performed in the same way as above.
With the operation downloadMultipleDocuments
we can download a list of resources at once with one request. The resources will be then zipped and delivered as expected.
The following curl
command demonstrates how to download multiple resources with Application Layer graphql api:
curl -v --basic -u admin:admin -O -J http://localhost:8080/nscalealinst1/graphql ^
-F operations="{\"query\":\"query downloadDocuments($resKeys: [String]!){
repositoryService {
downloadMultipleDocuments(resourceKeys: $resKeys)
}
}\",
\"variables\":{\"resKeys\":[\"da$NOTSET$154$2$NOTSET\",
\"da$NOTSET$153$2$NOTSET\"]}}"