diff --git a/docs/source/getting-started/app-architecture.rst b/docs/source/getting-started/app-architecture.rst index aa57d63036..3819c97a57 100644 --- a/docs/source/getting-started/app-architecture.rst +++ b/docs/source/getting-started/app-architecture.rst @@ -4,10 +4,10 @@ App Architecture **************** -In this section we'll look at the different components of our social network app. The goal is to familiarize you enough to feel comfortable extending the code with a new feature in the next section. There are two main components: +In this section we'll look at the different components of the social network app we created in `Building Your App `_. The goal is to familiarize yourself with the basics of Daml architecture enough to feel comfortable extending the code with a new feature in the next section. There are two main components: - * the Daml model and - * the React/TypeScript frontend. + * the Daml model + * the React/TypeScript frontend We generate TypeScript code to bridge the two. @@ -25,7 +25,7 @@ In your terminal, navigate to the root ``create-daml-app`` directory and run:: daml studio This should open the Visual Studio Code editor at the root of the project. -(You may get a new tab pop up with release notes for the latest version of Daml - just close this.) +(You may get a new tab pop up with release notes for the latest version of Daml - close this.) Using the file *Explorer* on the left sidebar, navigate to the ``daml`` folder and double-click on the ``User.daml`` file. The Daml code defines the *data* and *workflow* of the application. @@ -48,14 +48,15 @@ The signatories are the parties whose authorization is required to create or arc The observers are the parties who are able to view the contract on the ledger. In this case all users that a particular user is following are able to see the user contract. +A note on naming is also in order here. Each party has both a unique random string that defines that party, and a human-readable user name that is used at login. In addition, a user can set a display name or alias that is visible to other users. Only the alias can be changed. Clicking on a contract will show you the party’s unique string, not the user name or alias. + Let's see what the ``signatory`` and ``observer`` clauses mean in our app more concretely. -A user Alice can see another user Bob in the network only when Bob is following Alice (only if Alice is in the ``following`` list in his user contract). -For this to be true, Bob must have previously started to follow Alice, as he is the sole signatory on his user contract. +The user with the alias Alice can see another user, alias Bob, in the network only when Bob is following Alice (only if Alice is in the ``following`` list in his user contract). For this to be true, Bob must have previously started to follow Alice, as he is the sole signatory on his user contract. If not, Bob will be invisible to Alice. -Here we see two concepts that are central to Daml: *authorization* and *privacy*. +This illustrates two concepts that are central to Daml: *authorization* and *privacy*. Authorization is about who can *do* what, and privacy is about who can *see* what. -In Daml we must answer these questions upfront, as they fundamentally change the design of an application. +In Daml you must answer these questions upfront, as they are fundamental to the design of the application. The last part of the Daml model is the operation to follow users, called a *choice* in Daml. @@ -64,7 +65,7 @@ The last part of the Daml model is the operation to follow users, called a *choi :start-after: -- FOLLOW_BEGIN :end-before: -- FOLLOW_END -Daml contracts are *immutable* (can not be changed in place), so the only way to "update" one is to archive it and create a new instance. +Daml contracts are *immutable* (can not be changed in place), so the only way to update one is to archive it and create a new instance. That is what the ``Follow`` choice does: after checking some preconditions, it archives the current user contract and creates a new one with the new user to follow added to the list. Here is a quick explanation of the code: - The choice starts with the ``nonconsuming choice`` keyword followed by the choice name ``Follow``. @@ -75,7 +76,7 @@ That is what the ``Follow`` choice does: after checking some preconditions, it a - After passing some checks, the current contract is archived with ``archive self``. - A new ``User`` contract with the new user we have started following is created (the new user is added to the ``following`` list). -This information should be enough for understanding how choices work in this guide. More detailed information on choices can be found in :doc:`our docs `. +More detailed information on choices can be found in :doc:`our docs `. Let's move on to how our Daml model is reflected and used on the UI side. @@ -85,7 +86,7 @@ TypeScript Code Generation The user interface for our app is written in `TypeScript `_. TypeScript is a variant of JavaScript that provides more support during development through its type system. -In order to build an application on top of Daml, we need a way to refer to our Daml templates and choices in TypeScript. +To build an application on top of Daml, we need a way to refer to our Daml templates and choices in TypeScript. We do this using a Daml to TypeScript code generation tool in the SDK. To run code generation, we first need to compile the Daml model to an archive format (a ``.dar`` file). @@ -114,13 +115,13 @@ We'll first look at ``App.tsx``, which is the entry point to our application. :end-before: // APP_END An important tool in the design of our components is a React feature called `Hooks `_. -Hooks allow you to share and update state across components, avoiding having to thread it through manually. -We take advantage of hooks in particular to share ledger state across components. -We use custom :doc:`Daml React hooks ` to query the ledger for contracts, create new contracts, and exercise choices. This is the library you will be using the most when interacting with the ledger [#f1]_ . +Hooks allow you to share and update state across components, avoiding the need to thread it through manually. +We take advantage of hooks to share ledger state across components. +Custom :doc:`Daml React hooks ` query the ledger for contracts, create new contracts, and exercise choices. This is the library you will use most often when interacting with the ledger [#f1]_ . The ``useState`` hook (not specific to Daml) here keeps track of the user's credentials. If they are not set, we render the ``LoginScreen`` with a callback to ``setCredentials``. -If they are set, then we render the ``MainScreen`` of the app. +If they are set, we render the ``MainScreen`` of the app. This is wrapped in the ``DamlLedger`` component, a `React context `_ with a handle to the ledger. Let's move on to more advanced uses of our Daml React library. @@ -132,7 +133,7 @@ It uses Daml React hooks to query and update ledger state. :start-after: // USERS_BEGIN :end-before: // USERS_END -The ``useParty`` hook simply returns the current user as stored in the ``DamlLedger`` context. +The ``useParty`` hook returns the current user as stored in the ``DamlLedger`` context. A more interesting example is the ``allUsers`` line. This uses the ``useStreamQueries`` hook to get all ``User`` contracts on the ledger. (``User.User`` here is an object generated by ``daml codegen js`` - it stores metadata of the ``User`` template defined in ``User.daml``.) @@ -140,7 +141,7 @@ Note however that this query preserves privacy: only users that follow the curre This behaviour is due to the observers on the ``User`` contract being exactly in the list of users that the current user is following. A final point on this is the *streaming* aspect of the query. -This means that results are updated as they come in - there is no need for periodic or manual reloading to see updates. +Results are updated as they come in - there is no need for periodic or manual reloading to see updates. Another example, showing how to *update* ledger state, is how we exercise the ``Follow`` choice of the ``User`` template. @@ -154,7 +155,7 @@ The core of the ``follow`` function here is the call to ``ledger.exerciseByKey`` The *key* in this case is the username of the current user, used to look up the corresponding ``User`` contract. The wrapper function ``follow`` is then passed to the subcomponents of ``MainView``. For example, ``follow`` is passed to the ``UserList`` component as an argument (a `prop `_ in React terms). -This gets triggered when you click the icon next to a user's name in the *Network* panel. +This is triggered when you click the icon next to a user's name in the *Network* panel. .. literalinclude:: code/templates-tarball/create-daml-app/ui/src/components/MainView.tsx :language: tsx @@ -166,4 +167,4 @@ You'll see this more as you develop :doc:`your first feature ` fo .. rubric:: Footnotes -.. [#f1] FYI Behind the scenes the Daml React hooks library uses the :doc:`Daml Ledger TypeScript library ` to communicate with a ledger implementation via the :doc:`HTTP JSON API `. +.. [#f1] Behind the scenes the Daml React hooks library uses the :doc:`Daml Ledger TypeScript library ` to communicate with a ledger implementation via the :doc:`HTTP JSON API `.