-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapis_and_structured_data.html
More file actions
290 lines (244 loc) · 12 KB
/
apis_and_structured_data.html
File metadata and controls
290 lines (244 loc) · 12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Working with APIs & Structured Data (JavaScript)</title>
<link rel="stylesheet" href="style/style.css" />
<script src="js/index.js"></script>
</head>
<body>
<div id="nav-placeholder"></div>
<div class="layout">
<aside class="sidebar">
<h2>Workshop</h2>
<nav>
<ul>
<li><a href="#overview">Overview</a></li>
<li><a href="#apis">What Are APIs?</a></li>
<li><a href="#formats">Data Formats</a></li>
<li><a href="#nws">NWS API</a></li>
<li><a href="#exercise_1">Mini Exercise</a></li>
<li><a href="#geolocation">Using Location</a></li>
<li><a href="#fetch">Fetching Data</a></li>
<li><a href="#then">Then What</a></li>
<li><a href="#loop">Looping & Tables</a></li>
<li><a href="#exercise_2">Mini Exercise</a></li>
<li><a href="#web_service">Web Services</a></li>
</ul>
</nav>
</aside>
<main class="content">
<header>
<h1>Working with APIs & Structured Data</h1>
<p class="subtitle">A 2-hour practical workshop for researchers using JavaScript to work with data, starting from <a href="examples/lesson_2.zip">lesson_2.zip</a></p>
</header>
<section id="overview">
<h2>Overview</h2>
<p>This workshop introduces <strong>Application Programming Interfaces (APIs)</strong> and structured data formats commonly used in research and public data portals.</p>
<p>Participants will learn how to request data from an API, interpret structured responses, and display results in a clean, readable format using JavaScript.</p>
<ul>
<li><strong>Duration:</strong> 2 hours</li>
<li><strong>Outcome:</strong> A webpage that automatically loads and displays weather forecast data</li>
</ul>
</section>
<section id="apis">
<h2>What Are APIs?</h2>
<p>An API is a structured way for software systems to share data. For researchers, APIs provide <strong>programmatic access</strong> to datasets that are frequently updated or too large to download manually.</p>
<p>Common research uses of APIs include:</p>
<ul>
<li>Accessing public datasets (environmental data, census, etc.)</li>
<li>Automating data collection (e.g., fetching weather data every hour)</li>
<li>Ensuring reproducibility</li>
<li>Building interactive research outputs</li>
</ul>
</section>
<section id="formats">
<h2>Common Structured Data Formats</h2>
<h3>JSON</h3>
<p>JavaScript Object Notation. Human-readable, widely used, and native to JavaScript.</p>
<h3>GeoJSON</h3>
<p>A geographic extension of JSON for spatial data (points, lines, polygons).</p>
<h3>CSV</h3>
<p>Comma-Separated Values. Common for spreadsheets and tabular research data.</p>
<h3>XML</h3>
<p>Extensible Markup Language. Older but still used in many scholarly systems.</p>
<p>In this workshop, we focus on <strong>JSON</strong> and <strong>GeoJSON</strong> because they work naturally with JavaScript.</p>
</section>
<section id="nws">
<h2>The National Weather Service (NWS) API</h2>
<p>The NWS provides a free, public API that returns weather forecasts in JSON format.</p>
<p>A typical request looks like this:</p>
<pre><code>https://api.weather.gov/points/39.7456,-97.0892</code></pre>
<p>This endpoint returns metadata, including a link to the forecast for that location.
See the <a href="https://www.weather.gov/documentation/services-web-api">NWS API Web Service</a> page for details.</p>
</section>
<section id="exercise_1">
<h2>Mini Exercise (5–7 min)</h2>
<p>Explore the NWS API response in your browser.</p>
<ul>
<li>Install a json-formatter extension in your browser (e.g., JSON Formatter for Chrome)</li>
<li>Open <a href="https://api.weather.gov/points/39.7456,-97.0892">https://api.weather.gov/points/39.7456,-97.0892</a></li>
<li>Notice how the data is organized</li>
</ul>
</section>
<section id="geolocation">
<h2>Using the Visitor’s Location</h2>
<p>Instead of hard-coding latitude and longitude, we can use the browser’s <i><a href="https://developer.mozilla.org/en-US/docs/Web/API/Navigator">navigator</a>.geolocation</i> API.</p>
<pre><code>navigator.geolocation.getCurrentPosition(position => {
const lat = position.coords.latitude;
const lon = position.coords.longitude;
});</code></pre>
<p>These coordinates can then be used to replace <i>39.7456,-97.0892</i> dynamically.</p>
</section>
<section id="fetch">
<h2>Fetching Data with JavaScript</h2>
<p>JavaScript uses the <i>fetch()</i> function to request data from an API.</p>
<pre><code>
async function get_weather_forcast(lat, lon) {
console.log("Fetching forecast for:", lat, lon);
const pointsRes = await fetch(`https://api.weather.gov/points/${lat},${lon}`);
const pointsData = await pointsRes.json();
const forecastRes = await fetch(pointsData.properties.forecast);
return await forecastRes.json();
}
</code></pre>
<p><i>fetch()</i> returns a <b>Promise</b>, not the data,
and is often used with the following to complete the request:</p>
<ol>
<li><i>async</i> allows operations to run without blocking the main program thread, ensuring the application remains responsive</li>
<li><i>await</i> used to pause the execution of an async function until a Promise is settled (fulfilled or rejected)</li>
</ol>
<p>This chained request pattern is common when working with linked APIs.</p>
</section>
<section id="then">
<h2>Then What</h2>
<p><i>.then()</i> is a method used with Promises to handle the results of asynchronous operations.
The updated <i>geolocation</i> below shows how to work with <i>.then()</i></p>
<pre><code>
navigator.geolocation.getCurrentPosition(position => {
let lat = position.coords.latitude;
let lon = position.coords.longitude;
get_weather_forcast(lat,lon)
.then(data => {
update_forcast(data);
}
)
});
</code></pre>
</section>
<section id="loop">
<h2>Looping Over Forecast Data</h2>
<p>The forecast response includes an array of time periods. We can loop over this data and build a table.</p>
<pre><code>forecastData.properties.periods.forEach(period => {
console.log(period.name, period.temperature, period.shortForecast);
});</code></pre>
<h3>Displaying Data in a Table</h3>
<pre><code><table id="forecast">
<thead>
<tr>
<th>Period</th>
<th>Temperature</th>
<th>Forecast</th>
</tr>
</thead>
<tbody></tbody>
</table></code></pre>
<pre><code>
const tbody = document.querySelector('#forecast tbody');
tbody.innerHTML = ""; // Clear existing rows
forecastData.properties.periods.forEach(period => {
const row = document.createElement('tr');
row.innerHTML = `
<td>${period.name}</td>
<td>${period.temperature}°F</td>
<td>${period.shortForecast}</td>
`;
tbody.appendChild(row);
});</code></pre>
<p>This approach cleanly separates <strong>data retrieval</strong> from <strong>presentation</strong>.</p>
<p>
To make this table much more visually appealing, the following CSS can be used:
</p>
<pre><code>
table {
width: 100%;
border-collapse: collapse;
margin: 2rem 0;
font-size: 0.95rem;
background-color: #ffffff;
border-radius: 0.5rem;
overflow: hidden;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
}
thead {
background-color: #0f172a;
color: #ffffff;
}
thead th {
text-align: left;
padding: 0.75rem 1rem;
font-weight: 600;
letter-spacing: 0.02em;
}
tbody tr {
border-bottom: 1px solid #e5e7eb;
}
tbody tr:nth-child(even) {
background-color: #f8fafc;
}
tbody tr:hover {
background-color: #eef2ff;
}
td {
padding: 0.75rem 1rem;
vertical-align: top;
}
</code></pre>
</section>
<section id="exercise_2">
<h2>Mini Exercise (5–7 min)</h2>
<p>Update the HTML Table and JavaScript<i>forecastData</i> forEach loop to include the <i>icon</i> property</p>
<ul>
<li>Create new HTML <li>th</li> element</li>
<li>Update Javascript 'template' string</li>
</ul>
When you're done, save the file and test it in your web browser.
</section>
<section id ="web_service">
<h2>Web Services</h2>
<p>Web services are powerful network-accessible resources capable of being pulled into your website.
There are plenty of web services available for developers to use in their projects.</p>
<p>The <a href="https://livingatlas.arcgis.com/en/browse/">ArcGIS Living Atlas of the World</a> is a great index of these, with lots to choose from.
We'll use the <a href="https://www.arcgis.com/home/item.html?id=cb1886ff0a9d4156ba4d2fadd7e8a139">Current Weather and Wind Station Data</a>.<br/>
ArcGIS Online, the plaform that powers the ArcGIS Living Atlas, uses a consistent API structure for all its web services.</p>
<p>Let's look at how to work with this API and pull in some weather station data. From the Current Weather and Wind Station Data page,
you should see a link to the REST API on the right labled URL.
<ol>
<li>Navigating to this page will bring you to the <a href="https://services9.arcgis.com/RHVPKKiFTONKtxq3/arcgis/rest/services/NOAA_METAR_current_wind_speed_direction_v1/FeatureServer">REST Services Directory</a>.</li>
<li>From here, clicking the Layers link for <a href="https://services9.arcgis.com/RHVPKKiFTONKtxq3/ArcGIS/rest/services/NOAA_METAR_current_wind_speed_direction_v1/FeatureServer/0">stations</a>
will bring you to the Layer page for the station data.</li>
<li>On the bottom of this page is the link to query the data.
Clicking the <b>query</b> link reveals the <a href="https://services9.arcgis.com/RHVPKKiFTONKtxq3/ArcGIS/rest/services/NOAA_METAR_current_wind_speed_direction_v1/FeatureServer/0/query">Query:Stations</a> form.<br>
This complex form isn't as itimitating as it looks as we only have to fill out a few fields to get data back. Make the following entrys:
<ul>
<li>where: 1=1</li>
<li>outFields: *</li>
<li>And change the Formate to: GEOJSON</li>
</ul>
</li>
<li>Then click <b>Query (GET)</b></li>
</ol>
We'll use this URL in the next lesson.<br/>
Note: if you only want to return one record, set "Result Record Count:" to 1. Great to testing large datasets!
</p>
The complete code for this example can been seen at <a href="examples/lesson_3/">lesson 3</a>, and can be download from <a href="examples/lesson_3.zip">lesson_3.zip</a>.
<footer>
Homework: From <a href="https://colostate-my.sharepoint.com/:w:/g/personal/kaworth_colostate_edu/IQD-Ek8LDhBqTZWcCkIuDPPCAaYqu3OVDHnDz9MgD64tVCk?e=0RdwIt">Getting Started With Web Design</a>
and complete part: 3) Find Websites to Emulate (Not Copy) and 4) Create a Simple Wireframe.
<br/> <a href="maps_and_charts.html">Next Section</a>
</footer>
</main>
</div>
</body>
</html>