Skip to content
This repository was archived by the owner on Sep 29, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
cb3204e
draft changes for documentation changes after permissions change
Aug 12, 2022
4fc34a1
remove reference to legacy guests
Aug 13, 2022
90bdd4e
Fix grammar in permissions.phtml
Aug 13, 2022
c740c09
update list of query methods
Aug 13, 2022
7c8a0c1
updated pagination documentation
Aug 15, 2022
63b4b7d
Only external linkes have target blank
Aug 15, 2022
c0cd90f
revise how we presetn permissions
Aug 15, 2022
5e77682
Update app/views/docs/permissions.phtml
gewenyu99 Aug 16, 2022
028da09
Update app/views/docs/permissions.phtml
gewenyu99 Aug 16, 2022
5bf0ffc
Use correct gender neutral pronouns
Aug 16, 2022
91a278b
accept changes suggested by matej
Aug 16, 2022
bd04fac
Add 202 response code
Aug 16, 2022
521e737
Add escaped ""
gewenyu99 Aug 17, 2022
6d50f94
implements Steven's suggestions
Aug 17, 2022
c533742
Add 413 status code
Aug 17, 2022
526c9c5
removed un-needed offsets, consistent hyphenation of terms
Aug 18, 2022
9f9ed08
corrects spelling of required
Aug 18, 2022
64d5a6a
Update app/views/docs/command-line.phtml
gewenyu99 Aug 19, 2022
335940e
Update app/views/docs/databases.phtml
gewenyu99 Aug 19, 2022
7de2ccb
permissions suggestions from matej
Aug 19, 2022
6496988
Update app/views/docs/realtime.phtml
gewenyu99 Aug 19, 2022
feb804d
Merge branch 'feat-permissions-update' into feat-queries-update
gewenyu99 Aug 19, 2022
4484f4a
update index
Aug 19, 2022
8191e1b
addresses Christy's review comments
Aug 22, 2022
72e123a
addresserammatical suggestions
Aug 22, 2022
89f2f69
Merge branch 'feat-permissions-update' into feat-queries-update
gewenyu99 Aug 22, 2022
01c1750
address Christy and Eldad's review comments
Aug 22, 2022
68d310e
Update app/views/docs/databases.phtml
gewenyu99 Aug 22, 2022
5af68e1
fix notEqual syntax
Aug 22, 2022
fb5ffc7
no hyphenation for xxx-level security to match UI
Aug 22, 2022
2a376a4
Merge pull request #233 from appwrite/feat-permissions-update
christyjacob4 Aug 22, 2022
5dd6ffb
Merge branch '0.16.x' into feat-queries-update
gewenyu99 Aug 22, 2022
a423a23
Merge pull request #234 from appwrite/feat-queries-update
christyjacob4 Aug 23, 2022
e88804a
Merge pull request #237 from appwrite/response-codes
christyjacob4 Aug 23, 2022
55e5c67
formatting corrections in databases
Aug 23, 2022
d7b0677
fix grammar and links
Aug 23, 2022
be77c16
Grammar checks
Aug 24, 2022
cdc4e1a
update code examples for sorting
Aug 24, 2022
58c6f76
Apply suggestions from code review
christyjacob4 Sep 14, 2022
c96f907
feat: address review comments
christyjacob4 Sep 14, 2022
88033f4
feat: address review comments
christyjacob4 Sep 14, 2022
eddb009
feat: address review comments
christyjacob4 Sep 14, 2022
533aecb
feat: address review comments
christyjacob4 Sep 14, 2022
f52b0e6
Merge branch 'main' of https://github.com/appwrite/docs into 0.16.x
christyjacob4 Sep 14, 2022
8b450e5
Update app/views/docs/admin.phtml
christyjacob4 Sep 14, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/views/docs/admin.phtml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<p>The Appwrite API has two different modes it can use, the first mode is the client mode, which is the <b>default</b> mode, and the second one is the <b>admin</b> or server mode.</p>

<p>When using Appwrite from the client-side, you should go with the normal default mode. This mode allows every user of your project to access only resources he has granted access to. When running in admin mode, you remove Appwrite default access restriction and ultimately allow access to any of the resources available on your Appwrite project (files, documents, or collections).</p>
<p>When using Appwrite from the client-side, you should go with the normal default mode. This mode allows every user of your project to access only resources they have been granted access to. When running in admin mode, you remove Appwrite default access restriction and ultimately allow access to any of the resources available on your Appwrite project (files, documents, or collections).</p>

<p>For security reasons, the admin mode only works in combination with an API key. You can create an API key from the Appwrite console, and you can choose what scopes of access you are willing to grant your SDK.</p>

Expand Down
2 changes: 1 addition & 1 deletion app/views/docs/architecture.phtml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ $image = new View(__DIR__.'/../general/image.phtml');
<p>The Appwrite architecture allows to monitor and detect how the different microservices perform efficiently. Each microservice has its own usage metrics and logs to allow you to debug or scale it quickly. Using Docker, you can also limit the resource usage (CPU, Memory, Swap) by specific services.</p>

<h2>Responsibilities</h2>
<p>Each service in the stack has a specific type of workload he has to handle, like sending emails, executing cloud functions or logging user activity. All the heavy lifting workloads are delegated from the API service to the background workers consuming messages in an event-driven way from the Appwrite pub/sub mechanism (implemented using Redis). Using this design, we make sure the Appwrite API is fast, responsive and has to handle only critical sync operations as appropriate for a request->response based service that should respond as fast as possible for minimum latency.</p>
<p>Each service in the stack has a specific type of workload it has to handle, like sending emails, executing cloud functions or logging user activity. All the heavy lifting workloads are delegated from the API service to the background workers consuming messages in an event-driven way from the Appwrite pub/sub mechanism (implemented using Redis). Using this design, we make sure the Appwrite API is fast, responsive and has to handle only critical sync operations as appropriate for a request->response based service that should respond as fast as possible for minimum latency.</p>

<h2>Traefik</h2>

Expand Down
14 changes: 7 additions & 7 deletions app/views/docs/command-line.phtml
Original file line number Diff line number Diff line change
Expand Up @@ -138,15 +138,15 @@ brew install --HEAD appwrite</code></pre>
"collections": [
{
"$id": "6213bb2d567d8a206614",
"$read": [
"team:admin"
],
"$write": [
"team:admin"
"$permissions": [
"read(\"any\")",
"create(\"team:admin\")",
"update(\"team:admin\")",
"delete(\"team:admin\")",
],
"name": "Millenium Problems",
"enabled": true,
"permission": "collection",
"documentSecurity": false,
"attributes": [],
"indexes": []
}
Expand Down Expand Up @@ -297,7 +297,7 @@ brew install --HEAD appwrite</code></pre>
<p>To create a new document in an existing collection, use the `createDocument` command.</p>

<div class="ide margin-bottom" data-lang="bash" data-lang-label="CLI">
<pre class="line-numbers"><code class="prism language-bash" data-prism>appwrite databases createDocument --collectionId <ID> --documentId 'unique()' --data '{ "Name": "Iron Man" }' --read role:all team:abc</code></pre>
<pre class="line-numbers"><code class="prism language-bash" data-prism>appwrite databases createDocument --collectionId <ID> --documentId 'unique()' --data '{ "Name": "Iron Man" }' --permissions 'read("any")' 'write("team:abc")' </code></pre>
</div>

<h3><a href="/docs/command-line#configuration" id="configuration">Configuration</a></h3>
Expand Down
148 changes: 84 additions & 64 deletions app/views/docs/databases.phtml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

<p>
You can create your database by adding it to your Appwrite project's dashboard. Access the Databases Service settings from your project's left-hand navigation panel.
To create a new database, click the click the <b>Add Database</b> button. Name your new database and optionally provide a custom database ID instead of a randomly generated one.
To create a new database, click the <b>Add Database</b> button. Name your new database, and optionally provide a custom database ID.
</p>

<p>
Expand All @@ -33,25 +33,14 @@

<h3><a href="/docs/databases#permissions" id="permissions">Permissions</a></h3>
<p>
Once you create your collection, you will reach your collection's settings page, where you can choose the permission model for your collection. There are two types of permissions models available, each one with different pros and cons designed to be flexible to best match your use case.
Appwrite provides permissions to restrict access to documents at two levels, document and collection level. When a user has the appropriate type of <a href="/docs/permissions/">access permissions</a> granted at <b>either</b> the document or the collection level, they will be able to access or change the document. If the permission field is left empty, Client SDKs cannot access the document.
</p>

<h4>Document Level Permissions</h4>
<p>
With this permission model, you have granular access control over every document, and users will only be able to access documents for which they have explicit permissions. Document permissions are required in this permission model, and collection permissions are optional.
</p>
<p>Document level permissions grant access to individual documents. Document level permissions are only applied if Document Security is enabled in the settings of your collection.</p>

<h4>Collection Level Permissions</h4>
<p>
With collection-level permissions, you assign permissions once for every document in the collection's settings - users with "read" access to the collection can see all documents in that collection. This permission model requires you to set collection permissions on the collection settings page. Document permissions are optional and will not be evaluated even when set.
</p>

<div class="notice margin-top-large margin-bottom-large">
<h5>Active Session Required</h5>

<p>For security purposes, an active Account session is required to create resources. So, even if wildcard write permissions are set, only logged-in users can create documents in a collection. If you require this behavior for your app, create an <a href="/docs/client/account?sdk=web-default#accountCreateAnonymousSession" target="_blank">anonymous session</a> first. An active session helps Appwrite enforce rate-control limits and protect your projects from intensive write operations.</p>
</div>

<p>Collection level permissions apply to every document in the collection.</p>

<h2><a href="/docs/databases#attributes" id="attributes">Create Attributes</a></h2>
<p>
Expand Down Expand Up @@ -211,7 +200,7 @@ func main() async throws {

<div class="notice margin-top-large margin-bottom-large">
<h4>Indexes Required</h4>
<p>You can only query correctly indexed queries. You can easily add new indexes from both the Appwrite console or one of the <a href="/docs/sdks#server" target="_blank">server SDKs</a>. Appwrite uses this limitation to enforce optimized queries for maximum performance and scalability of your collection. You can learn more about it on the <a href="/docs/databases#indexes">Appwrite Indexes</a> section.</p>
<p>You can only query indexed attributes. You can easily add new indexes from both the Appwrite console or any of the <a href="/docs/sdks#server">server SDKs</a>. Appwrite uses this limitation to enforce optimized queries for maximum performance and scalability of your collection. You can learn more about it in the <a href="/docs/databases#indexes">Appwrite Indexes</a> section.</p>
</div>
<p>
To find specific documents in a collection, pass an array of query strings as a parameter to the <a href="/docs/server/databases#databasesListDocuments">listDocuments</a> endpoint. The SDKs provide a <b>Query</b> class to make query building simpler:
Expand Down Expand Up @@ -301,42 +290,80 @@ func main() async throws{
</li>
</ul>

<p>The following operators are currently supported:</p>
<p>The following query methods are currently supported:</p>
<table cellspacing="0" cellpadding="0" border="0" class="full margin-bottom-large">
<thead>
<tr>
<th style="width: 250px">Operator</th>
<th style="width: 150px">Query Method</th>
<th>SDK Method Example</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>equal</td>
<td>Equal to.</td>
<td>Query.equal("title", ["Iron Man"])</td>
<td>Returns document if attribute is equal to any value in the provided array. Applies to any indexed attribute.</td>
</tr>
<tr>
<td>notEqual</td>
<td>Not equal to.</td>
<td>Query.notEqual("title", ["Iron Man"])</td>
<td>Returns document if attribute is not equal to any value in the provided array. Applies to any indexed attribute.</td>
</tr>
<tr>
<td>lesser</td>
<td>Lesser than.</td>
<td>lessThan</td>
<td>Query.lessThan("score", 10)</td>
<td>Returns document if attribute is less than the provided value. Applies to any indexed attribute.</td>
</tr>
<tr>
<td>lesserEqual</td>
<td>Less than or equal to.</td>
<td>lessThanEqual</td>
<td>Query.lessThanEqual("score", 10)</td>
<td>Returns document if attribute is less than or equal to the provided value. Applies to any indexed attribute.</td>
</tr>
<tr>
<td>greater</td>
<td>Greater than.</td>
<td>greaterThan</td>
<td>Query.greaterThan("score", 10)</td>
<td>Returns document if attribute is greater than the provided value. Applies to any indexed attribute.</td>
</tr>
<tr>
<td>greaterEqual</td>
<td>Greater than or equal to.</td>
<td>greaterThanEqual</td>
<td>Query.greaterThanEqual("score", 10)</td>
<td>Returns document if attribute is greater than or equal to the provided value. Applies to any indexed attribute.</td>
</tr>
<tr>
<td>search</td>
<td>Requires a Fulltext Index.</td>
<td>Query.search("text", "key words")</td>
<td>Searches string attributes for provided keywords. Applies to any string attribute with a full-text index.</td>
</tr>
<tr>
<td>orderDesc</td>
<td>Query.orderDesc("attribute")</td>
<td>Orders results in descending order by attribute. Attribute must be indexed. Pass in an empty string to return in natural order.</td>
</tr>
<tr>
<td>orderAsc</td>
<td>Query.orderAsc("attribute")</td>
<td>Orders results in ascending order by attribute. Attribute must be indexed. Pass in an empty string to return in natural order.</td>
</tr>
<tr>
<td>limit</td>
<td>Query.limit(25)</td>
<td>Limits the number of results returned by the query. Used for <a href="/docs/pagination#offset-pagination" id="offset-pagination">pagination</a>.</td>
</tr>
<tr>
<td>offset</td>
<td>Query.offset(0)</td>
<td>Offset the results returned by skipping some of the results. Used for <a href="/docs/pagination#offset-pagination" id="offset-pagination">pagination</a>.</td>
</tr>
<tr>
<td>cursorAfter</td>
<td>Query.cursorAfter("62a7...f620")</td>
<td>Places the cursor after the specified resource ID. Used for <a href="/docs/pagination#cursor-pagination" id="cursor-pagination">pagination</a>.</td>
</tr>
<tr>
<td>cursorBefore</td>
<td>Query.cursorBefore("62a7...a600")</td>
<td>Places the cursor before the specified resource ID. Used for <a href="/docs/pagination#cursor-pagination" id="cursor-pagination">pagination</a>.</td>
</tr>
</tbody>
</table>
Expand All @@ -351,7 +378,7 @@ const databases = new Databases(client, "[DATABASE_ID]"); // 'client' comes fro

databases.listDocuments('movies', [
Query.equal('title', ['Avatar', 'Lord of the Rings']),
Query.greater('year', 1999)
Query.greaterThan('year', 1999)
]);</code></pre>
</div>
</li>
Expand All @@ -368,7 +395,7 @@ void main() async {
collectionId: 'movies',
queries: [
Query.equal('title', ['Avatar', 'Lord of the Rings']),
Query.greater('year', 1999),
Query.greaterThan('year', 1999),
]);
print(docs.toMap());
} on AppwriteException catch(e) {
Expand Down Expand Up @@ -404,7 +431,7 @@ class MainActivity : AppCompatActivity() {
collectionId = "[COLLECTION_ID]",
queries = [
Query.equal("title", ["Avatar", "Lord of the Rings"]),
Query.greater("year", 1999),
Query.greaterThan("year", 1999),
],
)
val json = response.body?.string()
Expand All @@ -428,7 +455,7 @@ func main() async throws {
collectionId: "[COLLECTION_ID]",
queries: [
Query.equal("title", ["Avatar", "Lord of the Rings"]),
Query.greater("year", 1999)
Query.greaterThan("year", 1999)
]
)
print(list.toMap())
Expand All @@ -437,7 +464,7 @@ func main() async throws {
</li>
</ul>

<p>When performing a query against multiple attributes, a single index with all queries attributes is required. In the example above, a single index with <b>both</b> <span class="tag">title</span> and <span class="tag">year</span> is queried.</p>
<p>When performing a query against multiple attributes, a single index with all query attributes is required. In the example above, a single index with <b>both</b> <span class="tag">title</span> and <span class="tag">year</span> is required.</p>

<h2><a href="/docs/databases#indexes" id="indexes">Indexes</a></h2>
<p>
Expand Down Expand Up @@ -473,10 +500,7 @@ func main() async throws {
</table>

<h3><a href="/docs/databases#ordering" id="ordering">Ordering Results</a></h3>
<p>When querying using the <a href="/docs/server/databases#databasesListDocuments">listDocuments</a> endpoint, you can specify the order of the documents returned by providing the <b>orderAttributes</b> and <b>orderTypes</b> parameters. The results will be sorted by <b>$id</b> (create date) in ascending order when no order parameters are provided.</p>

<p>The parameter <b>orderAttributes</b> takes a string array of attributes IDs. The <b>orderTypes</b> parameter takes a string array equal in length to <b>orderAttributes</b> that indicate if each attribute should be sorted in ascending or descending order. Ascending and descending is denoted as <span class="tag">"ASC"</span> and <span class="tag">"DESC"</span> respectively.</p>

<p>When querying using the <a href="/docs/server/databases#databasesListDocuments">listDocuments</a> endpoint, you can specify the order of the documents returned using the "Query.orderAsc()" and "Query.orderDesc()" query methods.</p>

<ul class="phases clear" data-ui-phases>
<li>
Expand All @@ -486,13 +510,9 @@ func main() async throws {
const databases = new Databases(client, "[DATABASE_ID]"); // 'client' comes from setup
databases.listDocuments(
'movies', // collectionId
[], // queries
25, // limit
0, // offset
'', // cursor
'after', // cursorDirection
['title'], // orderAttributes
['ASC'] // orderTypes
[
Query.orderAsc('title'), // Order results in ascending order by title
], // queries
);</code></pre>
</div>
</li>
Expand All @@ -507,8 +527,7 @@ void main() async {
try {
final docs = await databases.listDocuments(
collectionId: 'movies',
orderAttributes: ['title'],
orderTypes: ['ASC']
query: [ Query.orderAsc('title') ]
);
print(docs.toMap());
} on AppwriteException catch(e) {
Expand Down Expand Up @@ -542,8 +561,7 @@ class MainActivity : AppCompatActivity() {
GlobalScope.launch {
val response = databases.listDocuments(
collectionId = "movies",
orderAttributes = listOf("title"),
orderTypes = listOf("ASC")
query = [ Query.orderAsc("title") ]
)
val json = response.body?.string()
}
Expand All @@ -564,8 +582,7 @@ func main() async throws {
let databases = Databases(client, "[DATABASE_ID]")
let list = try await databases.listDocuments(
collectionId: "movies",
orderAttributes: ["title"],
orderTypes: ["ASC"]
query: [ Query.orderAsc("title") ]
)
print(list.toMap())
}</code></pre>
Expand All @@ -583,13 +600,10 @@ func main() async throws {
const databases = new Databases(client, "[DATABASE_ID]"); // 'client' comes from setup
databases.listDocuments(
'movies', // collectionId
[], // query
25, // limit
0, // offset
'', // cursor
'after', // cursorDirection
['title', 'year'], // orderAttributes
['ASC', 'DESC'] // orderTypes
[
Query.orderAsc('title'), // Order by title in ascending order
Query.orderDesc('year') // Order by year in descending order
]
);</code></pre>
</div>
</li>
Expand All @@ -604,8 +618,10 @@ void main() async {
try {
final docs = await databases.listDocuments(
collectionId: 'movies',
orderAttributes: ['title', 'year'],
orderTypes: ['ASC', 'DESC']
query: [
Query.orderAsc('title'), // Order by title in ascending order
Query.orderDesc('year') // Order by year in descending order
]
);
print(docs.toMap());
} on AppwriteException catch(e) {
Expand Down Expand Up @@ -639,8 +655,10 @@ class MainActivity : AppCompatActivity() {
GlobalScope.launch {
val response = databases.listDocuments(
collectionId = "movies",
orderAttributes = listOf("title", "year"),
orderTypes = listOf("ASC", "DESC")
query = [
Query.orderAsc("title"), // Order by title in ascending order
Query.orderDesc("year") // Order by year in descending order
]
)
val json = response.body?.string()
}
Expand All @@ -661,8 +679,10 @@ func main() async throws {
let databases = Databases(client, "[DATABASE_ID]")
let list = try await databases.listDocuments(
collectionId: "movies",
orderAttributes: ["title", "year"],
orderTypes: ["ASC", "DESC"]
query: [
Query.orderAsc("title"), // Order by title in ascending order
Query.orderDesc("year") // Order by year in descending order
]
)
print(list.toMap())
}</code></pre>
Expand Down
Loading