Skip to content

Commit 0f2773b

Browse files
committed
add validation and verbosity to help users to understand what could be wrong with their endpoints
1 parent 948fdc3 commit 0f2773b

File tree

1 file changed

+67
-2
lines changed

1 file changed

+67
-2
lines changed

chapters/exercise-calling-data.qmd

Lines changed: 67 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,11 @@ Because the first question is about searching within a specific scope, let's sta
2424
| Parameter | Format | Notes |
2525
|-----------|--------|-------|
2626
| `q` | Search term e.g. sunflowers | Returns a listing of all Object IDs for objects that contain the search query within the object’s data |
27-
| `departmentId` | Integer | Returns objects that are a part of a specific department. For a list of departments and department IDs, refer to our /department endpoint: https://collectionapi.metmuseum.org/public/collection/v1/departments |
27+
| `departmentId` | Integer | Returns objects that are a part of a specific department. For a list of departments and department IDs, refer to our <span style="background-color: #fff3cd;">**/department endpoint**: https://collectionapi.metmuseum.org/public/collection/v1/departments </span> |
2828

2929
As you can see, documentation is the best starting point to interact with an API. With that information, we have answered not only the first question, but also what endpoint, parameters, and previous information we need to retrieve before doing the query.
3030

31-
Before proceeding with the next question, let's get the list of departments and their IDs to select the one corresponding to the 'Medieval Art' department. To do that, just paste the '/department' endpoint as is pointed out in the documentation.
31+
Before proceeding with the next question, let's get the list of departments and their IDs to select the one corresponding to the 'Medieval Art' department. To do that, just paste the '/department' endpoint as is pointed out in the documentation (if you get lost, follow the hints ;) ).
3232

3333
```{ojs}
3434
@@ -41,6 +41,60 @@ viewof departmentListEndpoint = Inputs.text({
4141
}
4242
})
4343
44+
async function validateEndpoint(endpoint) {
45+
const checks = [
46+
{
47+
pattern: /^https:\/\//,
48+
message: "URL must start with 'https://'"
49+
},
50+
{
51+
pattern: /collectionapi\.metmuseum\.org/,
52+
message: "URL must contain 'collectionapi.metmuseum.org'"
53+
},
54+
{
55+
pattern: /\/public\//,
56+
message: "Missing '/public/' in the path"
57+
},
58+
{
59+
pattern: /\/collection\//,
60+
message: "Missing '/collection/' in the path"
61+
},
62+
{
63+
pattern: /\/v1\//,
64+
message: "Missing '/v1/' in the path"
65+
},
66+
{
67+
pattern: /departments$/,
68+
message: "URL must end with 'departments'"
69+
}
70+
];
71+
72+
if (/[^:]\/\//.test(endpoint)) {
73+
return "Invalid URL: Contains double slashes (//)";
74+
}
75+
76+
const segments = ['collectionapi.metmuseum.org', 'public', 'collection', 'v1', 'departments'];
77+
for (let i = 0; i < segments.length - 1; i++) {
78+
const pattern = new RegExp(`${segments[i]}[^/]+${segments[i + 1]}`);
79+
if (pattern.test(endpoint)) {
80+
return `Missing slash between '${segments[i]}' and '${segments[i + 1]}'`;
81+
}
82+
}
83+
84+
for (const check of checks) {
85+
if (!check.pattern.test(endpoint)) {
86+
return check.message;
87+
}
88+
}
89+
90+
const expectedPattern = /^https:\/\/collectionapi\.metmuseum\.org\/public\/collection\/v1\/departments$/;
91+
if (!expectedPattern.test(endpoint)) {
92+
return "URL format is incorrect. Should be: https://collectionapi.metmuseum.org/public/collection/v1/departments";
93+
}
94+
95+
return null;
96+
}
97+
4498
async function fetchDepartmentList(endpoint) {
4599
try {
46100
const response = await fetch(endpoint);
@@ -70,6 +124,17 @@ async function fetchDepartmentList(endpoint) {
70124
71125
departmentList = {
72126
if (departmentListEndpoint) {
127+
const validation = await validateEndpoint(departmentListEndpoint);
128+
if (validation) {
129+
return {
130+
data: { "Message": validation },
131+
status: {
132+
code: 400,
133+
ok: false,
134+
text: "Bad Request"
135+
}
136+
};
137+
}
73138
const result = await fetchDepartmentList(departmentListEndpoint);
74139
return result;
75140
} else {

0 commit comments

Comments
 (0)