Skip to content

Commit 81479e0

Browse files
committed
Added typescript quickstart page
1 parent 2f5e97d commit 81479e0

File tree

3 files changed

+330
-0
lines changed

3 files changed

+330
-0
lines changed

docs/source-2.0/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ Read more
157157
:maxdepth: 1
158158

159159
java/index
160+
typescript/index
160161

161162
.. toctree::
162163
:caption: Project
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
====
2+
TypeScript
3+
====
4+
5+
.. toctree::
6+
:maxdepth: 1
7+
8+
quickstart
9+
10+
.. toctree::
11+
:caption: References
12+
:maxdepth: 1
13+
14+
Source code <https://github.com/smithy-lang/smithy-typescript>
Lines changed: 315 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,315 @@
1+
===============
2+
TypeScript Quickstart
3+
===============
4+
5+
This guide introduces `Smithy TypeScript <https://github.com/smithy-lang/smithy-typescript>`_ with a simple working example of a
6+
generated server and client.
7+
8+
For this example, imagine that you are the proud owner of a coffee shop.
9+
Your API allows your customers to order some *typescript* from their TypeScript applications.
10+
Users can use your SDK to list available coffees, order a coffee, and track the status of their order.
11+
12+
.. admonition:: Review
13+
:class: tip
14+
15+
If you are new to Smithy or just need a refresher on the basics, you may find it helpful to work through the
16+
Smithy :doc:`../quickstart`.
17+
18+
-------------
19+
Prerequisites
20+
-------------
21+
22+
* :doc:`Smithy CLI <../guides/smithy-cli/cli_installation>`
23+
* `Node.js (>= 16) <https://nodejs.org/en/download>`_ and `yarn <https://yarnpkg.com/getting-started/install>`_
24+
* Ensure you have the Smithy CLI installed. Run ``smithy --version`` to confirm the CLI is correctly installed.
25+
If you need to install the CLI, see :doc:`Smithy CLI Installation <../guides/smithy-cli/cli_installation>`.
26+
.. warning:: This project was made for Mac/Linux, it may not build correctly on Windows.
27+
28+
------
29+
Set Up
30+
------
31+
32+
Clone the `quickstart example template <https://github.com/smithy-lang/smithy-examples/tree/main/smithy-typescript-examples/quickstart-typescript>`_
33+
using the Smithy CLI ``init`` command and change to the cloned directory:
34+
35+
.. code-block:: sh
36+
37+
smithy init -t smithy-typescript-quickstart && cd smithy-typescript-quickstart
38+
39+
The directory tree of the project should look like:
40+
41+
.. code-block:: sh
42+
43+
smithy-typescript-quickstart/
44+
├── smithy
45+
│ ├── ...
46+
├── client
47+
│ ├── ...
48+
├── server
49+
│ ├── ...
50+
├── README.md
51+
└── ...
52+
53+
The example project contains a number of packages:
54+
55+
* ``smithy/``: Common package for the service API model. Used by both client and server packages.
56+
* ``server/``: Code generated Server that implements stubbed operations code-generated from the service model.
57+
* ``client/``: Code generated client that can call the server.
58+
59+
60+
-------------
61+
Service Model
62+
-------------
63+
64+
The Smithy API model for our service can be found in the model package. This model defines the interface of our service and
65+
guides the generation of client and server code.
66+
67+
The service provides a few capabilities:
68+
69+
* Get a menu of available coffees with descriptions
70+
* The ability to order a coffee.
71+
* The ability to check the status of an order.
72+
73+
The service has the ``@restJson1`` protocol trait applied indicating that the service supports the :ref:`AWS restJson1 protocol <aws-restjson1-protocol>`.
74+
75+
.. code-block:: smithy
76+
:caption: smithy/model/weather.smithy
77+
78+
/// Allows users to retrieve a menu, create a coffee order, and
79+
/// and to view the status of their orders
80+
@title("Coffee Shop Service")
81+
@restJson1
82+
service CoffeeShop {
83+
...
84+
}
85+
86+
Protocols define the rules and conventions for serializing and de-serializing data when communicating between
87+
client and server.
88+
89+
Services can support multiple protocols at once.
90+
91+
From the root of the example project, build the service model using Gradle:
92+
93+
.. code-block:: sh
94+
95+
./gradlew clean build
96+
97+
-------------------
98+
Running the project
99+
-------------------
100+
101+
First, start the coffee shop service by executing the following command under ``server`` directory:
102+
103+
.. code-block:: sh
104+
105+
yarn setup && yarn start
106+
107+
This will start the coffee shop server on port ``8888`` and log the following to the console:
108+
109+
.. code-block:: sh
110+
:caption: terminal output
111+
112+
Started server on port 8888...
113+
handling orders...
114+
115+
To confirm the service is working, request the menu:
116+
117+
.. code-block:: sh
118+
119+
curl localhost:8888/menu
120+
121+
This will return a JSON-formatted menu of coffee types that can be ordered from our cafe:
122+
123+
.. code-block:: json
124+
125+
{
126+
"items": [
127+
{
128+
"type": "DRIP",
129+
"description": "A clean-bodied, rounder, and more simplistic flavour profile.\nOften praised for mellow and less intense notes.\nFar less concentrated than espresso.\n"
130+
},
131+
{
132+
"type": "POUR_OVER",
133+
"description": "Similar to drip coffee, but with a process that brings out more subtle nuances in flavor.\nMore concentrated than drip, but less than espresso.\n"
134+
},
135+
{
136+
"type": "LATTE",
137+
"description": "A creamier, milk-based drink made with espresso.\nA subtle coffee taste, with smooth texture.\nHigh milk-to-coffee ratio.\n"
138+
},
139+
{
140+
"type": "ESPRESSO",
141+
"description": "A highly concentrated form of coffee, brewed under high pressure.\nSyrupy, thick liquid in a small serving size.\nFull bodied and intensely aromatic.\n"
142+
}
143+
]
144+
}
145+
146+
.. tip::
147+
148+
Use the ``jq`` command line utility to pretty-print the output of the ``curl`` command above.
149+
150+
You may stop the server with ``CTRL + C`` in the terminal where it is running.
151+
With the server running, we can now call it with our client application.
152+
In a separate terminal, execute the client application under ``client`` directory :
153+
154+
.. code-block:: sh
155+
156+
yarn setup && yarn start
157+
158+
The client application will use a code-generated TypeScript SDK for the coffee shop service to:
159+
160+
1. Create a new coffee order for a refreshing COLD_BREW coffee,
161+
2. Wait a few seconds for the order to complete, and
162+
3. Call the service again to get the order.
163+
164+
The client terminal will print the following to the console (your order ID will differ):
165+
166+
.. code-block:: sh
167+
:caption: terminal output
168+
169+
Created request with id = 64a28313-c742-4442-a3ba-761111dea568
170+
Got order with id = 64a28313-c742-4442-a3ba-761111dea568
171+
Waiting for order to complete....
172+
Completed Order:{id:64a28313-c742-4442-a3ba-761111dea568, coffeeType:COLD_BREW, status:COMPLETED}
173+
174+
----------------------------
175+
Make a change to the service
176+
----------------------------
177+
178+
In this section, you will update the Coffee shop server application to support additional functionality.
179+
We would like to add a new operation to our service that allows users to get the hours of our cafe.
180+
181+
The new operation, ``GetHours``, should be bound directly to our service shape, take no input, and should return an output
182+
with both the opening and closing times. We will host this operation on the route ``/hours`` , and the reported hours
183+
will be expressed in hours using 24hr time (i.e. 1PM is 13).
184+
185+
Model Update
186+
============
187+
188+
First, the new operation must be added to our service model in the smithy package:
189+
190+
.. code-block:: diff
191+
:caption: smithy/model/main.smithy
192+
193+
service CoffeeShop {
194+
version: "2024-08-23"
195+
operations: [
196+
GetMenu,
197+
+ GetHours
198+
]
199+
resources: [
200+
Order
201+
]
202+
}
203+
204+
Then add the operation shape definition:
205+
206+
.. code-block::
207+
:caption: smithy/model/main.smithy
208+
209+
/// Retrieve the coffee shop hours.
210+
@http(method: "GET", uri: "/hours")
211+
@readonly
212+
operation GetHours{
213+
output := {
214+
opensAt: Hour
215+
closesAt: Hour
216+
}
217+
}
218+
219+
// Hours for a day expressed in 24hr time
220+
@range(min: 0, max: 24)
221+
integer Hour
222+
223+
Server Update
224+
=============
225+
226+
With our service model updated, we need to add the new functionality to our server. First, rebuild the project under the root directory:
227+
228+
.. code-block:: sh
229+
230+
./gradlew clean build
231+
232+
Let's try to start our server:
233+
234+
.. code-block:: sh
235+
236+
cd server && yarn start
237+
238+
This will fail with a compilation error:
239+
240+
.. code-block:: sh
241+
:caption: ``build`` output
242+
243+
src/CoffeeShop.ts:14:14 - error TS2420: Class 'CoffeeShop' incorrectly implements interface 'CoffeeShopService<CoffeeShopContext>'.
244+
Property 'GetHours' is missing in type 'CoffeeShop' but required in type 'CoffeeShopService<CoffeeShopContext>'.
245+
246+
247+
Smithy TypeScript **requires** that an implementation of a generated operation interface be registered with the server for
248+
every operation defined in service model. Let’s add the required implementation:
249+
250+
.. code-block:: TypeScript
251+
:caption: server/src/CoffeeShop.ts
252+
253+
async GetHours(context: CoffeeShopContext): Promise<GetHoursOutput> {
254+
return {
255+
opensAt: 9,
256+
closesAt: 16
257+
}
258+
}
259+
260+
Now, re-start our server:
261+
262+
.. code-block:: sh
263+
264+
yarn start
265+
266+
Finally, we can test the new operation using curl:
267+
268+
.. code-block:: sh
269+
270+
curl localhost:8888/hours
271+
272+
Which will return the hours of our Cafe:
273+
274+
.. code-block:: java
275+
:caption: ``curl`` output
276+
277+
{"opensAt":9,"closesAt":16}
278+
279+
Client Update
280+
=============
281+
282+
What if we want to call our new operation from our client application?
283+
The client code generator will automatically add the ``getHours`` operation to the generated client,
284+
we just need to call it in our client application:
285+
286+
.. code-block:: diff
287+
:caption: client/src/index.js
288+
289+
async function main() {
290+
try {
291+
+ const hours = await client.getHours()
292+
+ console.log(`Hours: Opens at: ${hours["opensAt"]}, Closes at ${hours["closesAt"]}`)
293+
// Create an order request
294+
const createRequest: CreateOrderInput = {
295+
coffeeType: CoffeeType.COLD_BREW
296+
};
297+
298+
With the server still running, call our client one more time:
299+
300+
.. code-block:: sh
301+
302+
yarn start
303+
304+
A new log line will now appear, listing the cafe’s hours:
305+
306+
.. code-block:: sh
307+
:caption: terminal output
308+
309+
Hours: Opens at: 9, Closes at: 16
310+
311+
----------
312+
Next steps
313+
----------
314+
315+
* Discover the Smithy ecosystem: `Awesome-Smithy <https://github.com/smithy-lang/awesome-smithy>`_

0 commit comments

Comments
 (0)