Skip to content

(DOCSP-39523): Consolidate Call a Function page #3322

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Jul 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
To call an Atlas Function, use the
:cpp-sdk:`call_function() <structrealm_1_1user.html#a82ab02822dd96e8d44201b996dd6ed0c>`
member function on the ``user`` object. Pass in the name of the
function as a string for the first parameter. This function takes two arguments,
which we provide as a string array of arguments.

The callback can provide an optional string result, or an optional error.
In this example, we check that the result has a value.
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
To call an Atlas Function, use the
:dotnet-sdk:`Functions.CallAsync() <reference/Realms.Sync.User.FunctionsClient.html#Realms_Sync_User_FunctionsClient_CallAsync_System_String_System_Object___>`
method on the ``User`` object, passing in the name of the function as the first
parameter and the arguments as the remaining parameters:

.. literalinclude:: /examples/generated/dotnet/FunctionExamples.snippet.callfunc.cs
:language: csharp

.. note::

The ``CallAsync()`` method returns a single ``BsonValue`` object, which you can
deserialize after calling the function or by using the generic
overload. Both of these approaches to deserialization are shown in the
code above.

A ``BsonValue`` object can hold a single primitive value (as shown in the
example above), or hold a complete BSON document. If
you have a class that maps to the returned object, you can deserialize
to that class by using the generic overload. For example, the following code
calls a function that returns an object from a collection of "RealmTasks".
Since we know the shape of the returned object, we we can deserialize the
``BsonValue`` to a class that we have created, and then we have
access to the properties and methods on that object:
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
To call a Function, call :flutter-sdk:`User.functions.call() <realm/FunctionsClient/call.html>`.
Pass the Function name as the first argument and all arguments for the Function
in a List as the second argument.

To include objects as arguments to the Function,
convert them to JSON first. You can do this using the `jsonEncode()
<https://api.flutter.dev/flutter/dart-convert/jsonEncode.html>`__
function included in the built-in ``dart:convert`` library.

The Function returns a ``dynamic`` value containing :manual:`MongoDB Extended JSON (EJSON)
</reference/mongodb-extended-json/>` deserialized to a native Dart object.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
To execute a function from the SDK, use the
:java-sdk:`getFunctions() <io/realm/mongodb/App.html#getFunctions(io.realm.mongodb.User)>`
method of the your :java-sdk:`App <io/realm/mongodb/App.html>`
to retrieve a :java-sdk:`Functions manager <io/realm/mongodb/functions/Functions.html>`.

Pass the name and parameters of the function you would like to call to
:java-sdk:`callFunction() <io/realm/mongodb/functions/Functions.html#callFunction(java.lang.String,java.util.List,java.lang.Class)>`
or :java-sdk:`callFunctionAsync() <io/realm/mongodb/functions/Functions.html#callFunctionAsync(java.lang.String,java.util.List,java.lang.Class,io.realm.mongodb.App.Callback)>`:
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
To call a function, you can either pass its name and arguments to
``User.callFunction()`` or call the function as if it was a method on the
:js-sdk:`User.functions <classes/User.html#functions>` property.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
To call an Atlas Function, pass its name and all arguments to
:kotlin-sync-sdk:`Functions.call() <io.realm.kotlin.mongodb.ext/call.html>`.

You can serialize Function arguments and return values using an EJSON encoder.
For more information, including examples, refer to :ref:`sdks-ejson-encoding-for-atlas`.

To call this Atlas Function from the SDK:
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
To execute a function in Objective-C, call the :objc-sdk:`callFunctionNamed:arguments:completionBlock:
<Classes/RLMUser.html#/c:objc(cs)RLMUser(im)callFunctionNamed:arguments:completionBlock:>`.
method on the :objc-sdk:`RLMUser <Classes/RLMUser.html>` object.

Provide the Function name, arguments, and completion block to execute when the
Function call is complete.
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
To execute a function in Swift, use the :swift-sdk:`functions
<Structs/Functions.html>` object on the currently logged-in user.

The ``functions`` object has dynamic members corresponding to functions.
In this case, ``functions.concatenate()`` refers to the ``concatenate``
function. Pass a ``BSONArray`` of arguments.

Async/Await
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Async/Await and Completion Handler headings are included in the on-this-page TOC for every language. But they only work for Swift because it's the only language with API details that include these headings.

Is the only way around this to remove the headers?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ugh, yes, I meant to make this page depth 1. Good catch, thank you!

```````````

.. literalinclude:: /examples/generated/code/start/Functions.snippet.async-call-a-function.swift
:language: swift

Completion Handler
``````````````````

The trailing closure is the completion handler to call when the function call
is complete. This handler is executed on a non-main global ``DispatchQueue``.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
.. tabs-drivers::

tabs:
- id: cpp-sdk
content: |

.. literalinclude:: /examples/generated/cpp/call-function.snippet.call-a-function.cpp
:language: cpp

- id: csharp
content: |

.. literalinclude:: /examples/generated/dotnet/FunctionExamples.snippet.callfuncWithPOCO.cs
:language: csharp

- id: dart
content: |

.. literalinclude:: /examples/generated/flutter/functions_test.snippet.call-function.dart
:language: dart

- id: java
content: |

.. literalinclude:: /examples/generated/java/sync/FunctionTest.snippet.call-a-function.java
:language: java
:emphasize-lines: 10-17

- id: java-kotlin
content: |

.. literalinclude:: /examples/generated/java/sync/FunctionTest.snippet.call-a-function.kt
:language: kotlin
:emphasize-lines: 8,9,10,11,12,13,14,15,16,17

- id: javascript
content: |

.. io-code-block::

.. input:: /examples/generated/node/call-a-function.snippet.call-a-function-by-name.js
:language: javascript

.. output::
:language: console

Using the "functions.sum()" method: the sum of 2 + 3 = 5
Using the "callFunction()" method: the sum of 2 + 3 = 5

- id: kotlin
content: |

.. literalinclude:: /examples/generated/kotlin/FunctionsTest.snippet.call-function.kt
:language: kotlin

- id: objectivec
content: |

.. literalinclude:: /examples/generated/code/start/Functions.snippet.call-a-function.m
:language: objectivec

- id: swift
content: |

.. literalinclude:: /examples/generated/code/start/Functions.snippet.call-a-function.swift
:language: swift

- id: typescript
content: |

.. io-code-block::

.. input:: /examples/generated/node/call-a-function.snippet.call-a-function-by-name.js
:language: javascript

.. output::
:language: console

Using the "functions.sum()" method: the sum of 2 + 3 = 5
Using the "callFunction()" method: the sum of 2 + 3 = 5
104 changes: 99 additions & 5 deletions source/sdk/atlas/call-function.txt
Original file line number Diff line number Diff line change
@@ -1,13 +1,107 @@
.. _sdks-call-function:

===============
Call a Function
===============
======================
Call an Atlas Function
======================

.. meta::
:description: Call serverless Atlas Functions from a client application with Atlas Device SDK.
:keywords: Realm, C++ SDK, Flutter SDK, Kotlin SDK, Java SDK, .NET SDK, Node.js SDK, Swift SDK, code example

.. facet::
:name: genre
:values: reference

.. facet::
:name: programming_language
:values: cpp, csharp, dart, java, javascript/typescript, kotlin, objective-c, swift

.. contents:: On this page
:local:
:backlinks: none
:depth: 2
:depth: 1
:class: singlecol

Placeholder page for the call a Function content.
.. tabs-selector:: drivers

You can call an **Atlas Function** from a client application using Atlas
Device SDK. Functions are serverless JavaScript functions that let you define
and execute server-side logic. These server-side Functions can run in the
context of the authenticated user, and thus honor the rules, roles, and
permissions that you have assigned to your data in Atlas.

For more information on configuring and writing Atlas Functions, refer to
:ref:`Atlas Functions <functions>` in the App Services documentation.

Before You Begin
----------------

#. In an App Services App, :ref:`define an Atlas Function <define-a-function>`.
#. In your client project, :ref:`initialize the App client <sdks-connect-to-atlas>`.
#. Then, :ref:`authenticate a user <sdks-authenticate-users>`. You access
Functions through the user object.

The example on this page demonstrates calling an :ref:`Atlas Function <functions>`
that takes two arguments, performs some work, and returns the result.

Call a Function
---------------

.. important::

Make sure to sanitize client data to protect against code injection when using
Functions.

.. tabs-drivers::

.. tab::
:tabid: cpp-sdk

.. include:: /includes/api-details/cpp/atlas/call-atlas-function-call-function-description.rst

.. tab::
:tabid: csharp

.. include:: /includes/api-details/csharp/atlas/call-atlas-function-call-function-description.rst

.. tab::
:tabid: dart

.. include:: /includes/api-details/dart/atlas/call-atlas-function-call-function-description.rst

.. tab::
:tabid: java

.. include:: /includes/api-details/java/atlas/call-atlas-function-call-function-description.rst

.. tab::
:tabid: java-kotlin

.. include:: /includes/api-details/java/atlas/call-atlas-function-call-function-description.rst

.. tab::
:tabid: javascript

.. include:: /includes/api-details/javascript/atlas/call-atlas-function-call-function-js-ts-description.rst

.. tab::
:tabid: kotlin

.. include:: /includes/api-details/kotlin/atlas/call-atlas-function-call-function-description.rst

.. tab::
:tabid: objectivec

.. include:: /includes/api-details/objectivec/atlas/call-atlas-function-call-function-description.rst

.. tab::
:tabid: swift

.. include:: /includes/api-details/swift/atlas/call-atlas-function-call-function-description.rst

.. tab::
:tabid: typescript

.. include:: /includes/api-details/javascript/atlas/call-atlas-function-call-function-js-ts-description.rst

.. include:: /includes/sdk-examples/atlas/call-atlas-function-call-function.rst
5 changes: 5 additions & 0 deletions source/sdk/serialization.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,8 @@ Serialization
:class: singlecol

Placeholder page for information about serialization in the SDKs.

.. _sdks-ejson-encoding-for-atlas:

EJSON Encoding
--------------
Loading