Update first-feature.rst

This commit is contained in:
carrielaben-da 2022-02-03 11:16:57 -05:00 committed by GitHub
parent 78ffa6d2c1
commit 120d894ad6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -4,32 +4,32 @@
Your First Feature
******************
Let's dive into implementing a new feature for our social network app.
This will give us a better idea how to develop Daml applications using our template.
To get a better idea of how to develop Daml applications, lets try implementing a new feature for our social network app.
At the moment, our app lets us follow users in the network, but we have no way to communicate with them!
At the moment, our app lets us follow users in the network, but we have no way to communicate with them.
Let's fix that by adding a *direct messaging* feature.
This should let users that follow each other send messages, respecting *authorization* and *privacy*.
This should let users that follow each other send messages to each other, respecting *authorization* and *privacy*.
This means:
1. You cannot send a message to someone unless they have given you the authority by following you back.
2. You cannot see a message unless you sent it or it was sent to you.
- You cannot send a message to someone unless they have given you the authority by following you back.
- You cannot see a message unless you sent it or it was sent to you.
We will see that Daml lets us implement these guarantees in a direct and intuitive way.
Daml lets us implement these guarantees in a direct and intuitive way.
There are three parts to building and running the messaging feature:
Creating a feature involves four steps:
1. Adding the necessary changes to the Daml model
2. Making the corresponding changes in the UI
3. Running the app with the new feature.
2. Running the feature
3. Making the corresponding changes in the UI
4. Running the app with the new feature
As usual, we must start with the Daml model and base our UI changes on top of that.
Daml Changes
============
As mentioned in the :doc:`architecture <app-architecture>` section, the Daml code defines the *data* and *workflow* of the application.
The workflow aspect refers to the interactions between parties that are permitted by the system.
The Daml code defines the *data* and *workflow* of the application; you can read about this in more detail in the :doc:`architecture <app-architecture>` section.
The workflow refers to the interactions between parties that are permitted by the system.
In the context of a messaging feature, these are essentially the authorization and privacy concerns listed above.
For the authorization part, we take the following approach: a user Bob can message another user Alice when Alice starts following Bob back.
@ -46,7 +46,7 @@ Indentation is important: it should be at the top level like the original ``User
This template is very simple: it contains the data for a message and no choices.
The interesting part is the ``signatory`` clause: both the ``sender`` and ``receiver`` are signatories on the template.
This enforces the fact that creation and archival of ``Message`` contracts must be authorized by both parties.
This enforces that creation and archival of ``Message`` contracts must be authorized by both parties.
Now we can add messaging into the workflow by adding a new choice to the ``User`` template.
Copy the following choice to the ``User`` template after the ``Follow`` choice. The indentation for the ``SendMessage`` choice must match the one of ``Follow`` . *Make sure you save the file after copying the code*.
@ -74,16 +74,15 @@ Navigate to the terminal window where the ``daml start`` process is running and
- Update the JavaScript library under ``ui/daml.js`` to connect the UI with your Daml code
- Upload the *new DAR file* to the sandbox
As mentioned at the beginning of this *Getting Started with Daml* guide, Daml Sandbox uses an
in-memory store, which means it loses its state when stopped or restarted. That means that all user
data and follower relationships are lost.
As mentioned previously, Daml Sandbox uses an
in-memory store, which means it loses its state which here includes all user data and follower relationships when stopped or restarted.
Now let's integrate the new functionality into the UI.
Messaging UI
============
The UI for messaging will consist of a new *Messages* panel in addition to the *Follow* and *Network* panel.
The UI for messaging consists of a new *Messages* panel in addition to the *Follow* and *Network* panel.
This panel will have two parts:
1. A list of messages you've received with their senders.
@ -97,7 +96,7 @@ MessageList Component
The goal of the ``MessageList`` component is to query all ``Message`` contracts where the ``receiver`` is the current user, and display their contents and senders in a list.
The entire component is shown below.
You should copy this into a new ``MessageList.tsx`` file in ``ui/src/components`` and save it.
Copy this into a new ``MessageList.tsx`` file in ``ui/src/components`` and save it.
.. TODO Include file in template with placeholder for component logic.
@ -111,8 +110,7 @@ The streaming aspect means that we don't need to reload the page when new messag
For each contract in the stream, we destructure the *payload* (the data as opposed to metadata like the contract ID) into the ``{sender, receiver, content}`` object pattern.
Then we construct a ``ListItem`` UI element with the details of the message.
There is one important point about privacy here.
No matter how we write our ``Message`` query in the UI code, it is impossible to break the privacy rules given by the Daml model.
An important point about privacy: no matter how we write our ``Message`` query in the UI code, it is impossible to break the privacy rules given by the Daml model.
That is, it is impossible to see a ``Message`` contract of which you are not the ``sender`` or the ``receiver`` (the only parties that can observe the contract).
This is a major benefit of writing apps on Daml: the burden of ensuring privacy and authorization is confined to the Daml model.
@ -120,7 +118,7 @@ MessageEdit Component
---------------------
Next we need the ``MessageEdit`` component to compose and send messages to our followers.
Again we show the entire component here; you should copy this into a new ``MessageEdit.tsx`` file in ``ui/src/components`` and save it.
Again we show the entire component here; copy this into a new ``MessageEdit.tsx`` file in ``ui/src/components`` and save it.
.. TODO Include file in template with placeholder for component logic.
@ -144,7 +142,7 @@ The result of a successful call to ``submitMessage`` is a new ``Message`` contra
The return value of this component is the React ``Form`` element.
This contains a dropdown menu to select a receiver from the ``followers``, a text field for the message content, and a *Send* button which triggers ``submitMessage``.
There is again an important point here, in this case about how *authorization* is enforced.
Note how *authorization* is enforced here.
Due to the logic of the ``SendMessage`` choice, it is impossible to send a message to a user who is not following us (even if you could somehow access their ``User`` contract).
The assertion that ``elem sender following`` in ``SendMessage`` ensures this: no mistake or malice by the UI programmer could breach this.
@ -161,24 +159,24 @@ Open the ``ui/src/components/MainView.tsx`` file and start by adding imports for
:end-before: // IMPORTS_END
Next, find where the *Network* ``Segment`` closes, towards the end of the component.
This is where we'll add a new ``Segment`` for *Messages*. Make sure you've saved the file after copying the code.
This is where we'll add a new ``Segment`` for *Messages*. Make sure you save the file after copying over the code.
.. literalinclude:: code/templates-tarball/create-daml-app/ui/src/components/MainView.tsx
:language: tsx
:start-after: {/* MESSAGES_SEGMENT_BEGIN */}
:end-before: {/* MESSAGES_SEGMENT_END */}
You can see we simply follow the formatting of the previous panels and include the new messaging components: ``MessageEdit`` supplied with the usernames of all visible parties as props, and ``MessageList`` to display all messages.
Following the formatting of the previous panels, we include the new messaging components: ``MessageEdit`` supplied with the usernames of all visible parties as props, and ``MessageList`` to display all messages.
That is all for the implementation!
Let's give the new functionality a spin.
Running the updated UI
Running the Updated UI
======================
If you have the frontend UI up and running you're all set. In case you don't have the UI running open a new terminal window and navigate to the ``create-daml-app/ui`` folder and run the ``npm start`` command, which will start the UI.
If you have the frontend UI up and running you're all set. If you don't have the UI running, open a new terminal window and navigate to the ``create-daml-app/ui`` folder, then run the ``npm start`` command to start the UI.
Once you've done all these changes you should see the same login page as before at http://localhost:3000.
You should see the same login page as before at http://localhost:3000.
.. figure:: images/create-daml-app-login-screen.png
:scale: 50 %
@ -190,15 +188,15 @@ Once you've logged in, you'll see a familiar UI but with our new *Messages* pane
.. figure:: images/create-daml-app-messaging-feature.png
:alt: You can now see the messaging feature in the create-daml-app
Go ahead and add follow more users, and log in as some of those users in separate browser windows to follow yourself back.
Then, if you click on the dropdown menu in the *Messages* panel, you'll be able to see some followers to message!
Go ahead and follow more users, and log in as some of those users in separate browser windows to follow yourself back.
Then click on the dropdown menu in the *Messages* panel to see a choice of followers to message!
.. figure:: images/create-daml-app-messaging-select-user.png
:scale: 50 %
:alt: Select a follower from a dropdown list in the create-daml-app
Send some messages between users and make sure you can see each one from the other side.
You'll notice that new messages appear in the UI as soon as they are sent (due to the *streaming* React hooks).
Notice that each new message appears in the UI as soon as it is sent (due to the *streaming* React hooks).
.. figure:: images/create-daml-app-message-received.png
:scale: 50 %