Exam 2023-08-20
Here you find sample answers and marking guidelines to the questions on the exam 2023-08-20.
Start by reading through all questions. Peter will not visit the exam. If you find any question unclear, ask the exam administrator (tentavakt in Swedish) to call Peter for clarification.
Max score is 25 points.
- For grade 3, 40% of max score (10 points) is required
- For grade 4, 60% of max score (15 points) is required
- For grade 5, 80% of max score (20 points) is required
You are not allowed to use anything else except:
- The computer you sit at to only answer the questions on this exam
- A dictionary to translate to/from English from/to your native language
- Pen and paper to sketch with (should not be submitted)
Write your answers in either English or Swedish. If you write your answers in Swedish, make sure to not introduce any translation confusement. Write proper sentences (spelling, upper/lower case characters, punctuation, etc.). Answers that do not do this good enough/are vague/are not understandable cannot receive full score on the questions,
Answers that are more or less copies of sample answers given to you or copies of text found somewhere else will be rewarded 0 points. Use your own words to answer the questions.
Good luck!
Client-Side JS
Question 1 (1p)
Question
In client-side JS, name three different methods we can call on the document
object to obtain references to HTML elements on the webpage (the method should either return a single reference, or multiple references (i.e. a NodeList/Array)).
Sample answer
getElementById
querySelector
querySelectorAll
Marking guidelines
- 0.33 points for each correct name
- Only 0.23 if spelling is wrong
Question 2 (1p)
Question
Name two different events that can fire on a webpage and that cause the web browser to send an HTTP request to load a new webpage.
Sample answer
click
(when a<a>
element is clicked)submit
(when a<form>
element is submitted)
Marking guidelines
- 0.5 points for each correct event name
Question 3 (1p)
Question
Explain when and how many times the event DOMContentLoaded
fires on a webpage.
Sample answer
The DOMContentLoaded
event is fired by the web browser each time it has loaded a new webpage from the HTML code in an HTTP response, so it fires once for each webpage that is shown.
Marking guidelines
- 0.5 point for when
- 0.5 points for how many times
Frontend framework
Question 4 (2p)
Question
In a frontend framework of your choice (name which one you choose), implement a component that works like this:
- The one using the component should be able to pass an array of integers to it
- If the array is empty, the component should display an HTML paragraph with the text
No integers
- If the array is not empty, the component should display the integers in an HTML ordered list:
- Each integer should be displayed in its own HTML list item
- Each integer should be displayed as it is (e.g.
5
should be displayed as5
), except0
, which should be displayed as the textZero
Sample answer
In Svelte:
<script>
export let integers
</script>
{#if integers.length == 0}
<p>No integers</p>
{:else}
<ol>
{#each integers as integer}
<li>
{#if integer == 0}
Zero
{:else}
{integer}
{/if}
</li>
{/each}
</ol>
{/if}
Marking guidelines
- 0.5 points for correct prop
- 0.5 points for using if correct
- 0.5 points for using loop correct
- 0.5 points for using else correct
- Point deductions for errors:
- -0.1 points for using
array.count
/array.isEmpty
instead ofarray.length
- -0.25 points for using extra variables not needed/not used
- -0.25 points for not using else, but inverted condition in an extra if
- -0.5 points for not naming which framework that is used
- -0.5 points for always showing
<ul>
- In Svelte:
- -0.1 points for
of
instead ofas
in#each
- -0.25 points for not using the
{ ... }
syntax in Svelte - -0.25 points for not using
#each
correct - -0.25 points for using
$
in front of variable name when it's not a store
- -0.1 points for
- -0.1 points for using
HTTP/REST API
Question 5 (1p)
Question
Match each status code to its corresponding reason phrase.
Status codes:
- 200
- 201
- 204
- 404
- 500
Reason Phrases:
- Internal Server Error
- No Content
- Not Found
- Created
- OK
You will get:
- 1 point for all correct
Sample answer
- 200 - OK
- 201 - Created
- 204 - No Content
- 404 - Not Found
- 500 - Internal Server Error
Marking guidelines
- 1 point for all correct
Question 6 (1p)
Question
In HTTP, explain when the Accept
header can be used, what it represents, and give an example of a value it can have, and explain what using the header with that value means.
Sample answer
The Accept
header can be used in an HTTP request to indicate which data format the client wants the body in the HTTP response to be written in. For example, the value application/json
would mean that the body in the response should be written in JSON format.
Marking guidelines
- 0.25 points for used in requests
- 0.25 points for what it represents
- 0.25 points sample value
- 0.25 points for what sample value means
Question 7 (2p)
Question
On a backend storing information about species, the following relational database table is used to store the species:
id | name | numberOfLegs |
---|---|---|
1 | Snake | 0 |
2 | Dog | 4 |
3 | Human | 2 |
4 | Cat | 4 |
... | ... | ... |
Your task is to design a REST API clients can use to update a species with a specific id
. The following validation rules should exist:
name
must contain at least 1 character- Two different species with the same
name
may not exist numberOfLegs
must be 0 or more
Someone who implements or uses your API should be able to get all details they need to know about the API from your design, so be sure to mention all relevant details they need to use/implement it.
Note: You don't need to worry about authorization in this task; any (anonymous) client should be allowed to update any species.
Note: If you think you are missing some important information you have to know to be able to carry out the task in a good way, feel free to make your own assumptions about that information, but clearly state which those assumptions are in your answer.
Sample answer
Words WRITTEN_LIKE_THIS
are placeholders for actual values.
Request:
- URI:
/species/THE_ACTUAL_ID
- Method:
PUT
- Headers:
Content-Type
:application/json
Content-Length
:THE_ACTUAL_NUMBER_OF_BYTES_IN_THE_BODY
- Body:
{"id": THE_ACTUAL_ID, "name": "THE_ACTUAL_NAME", "numberOfLegs": "THE_ACTUAL_NUMBER_OF_LEGS"}
Possible responses:
- If the server can't carry out the request because of some internal error:
- Status code:
500
- Status code:
- If there doesn't exist a species resource with
THE_ACTUAL_ID
:- Status code:
404
- Status code:
- If the resource was successfully updated
- Status code:
204
- Status code:
- If there are validation errors:
- Status code:
400
- Headers:
Content-Type
:application/json
Content-Length
:THE_ACTUAL_NUMBER_OF_BYTES_IN_THE_BODY
- Body:
["ERROR_CODE_1", "ERROR_CODE_2", ...]
- Available
ERROR_CODE_X
:NAME_TOO_SHORT
(name must contain at least 1 character)NAME_ALREADY_USED
(a species with the new name already exist)NUMBER_OF_LEGS_TOO_FEW
(must be at least 0)
- Available
- Status code:
Marking guidelines
- 0.5 points for request
- 0.5 points for handling success response
- 0.5 points for handling not found response
- 0.5 points for validation errors response
Point deduction:
- -0.1 points for each piece of information missing, such as:
- URI in request
- Method in request
- Crucial header in request (except
Content-Length
) - Body/property in body
- Crucial header in response
- Error code/message
- Etc.
- -0.1 points for each piece of information written that makes no sense
Question 8 (3p)
Question
Name and describe each constraint REST consists of.
Sample answer
See Chapter 5.1 Deriving REST in Roy Thomas Fielding's dissertation Architectural Styles and the Design of Network-based Software Architectures.
Marking guidelines
- 0.25 points for each correct name
- 0.25 points for each correct description
Question 9 (2p)
Question
Alice is assigned the task to design a REST API clients can use to login and then create new blogposts belonging to that account. She decides that when a user logs in, the client obtains an access token (THE.ACCESS.TOKEN
) containing the user's account id, which can be used to act on the behalf of that user. Then when the user wants to create a new blogpost belonging to her own account, the client sends an HTTP POST
request to /blogposts
with the headers Authorization: Bearer THE.ACCESS.TOKEN
and Content-Type: application/json
, and in the body pass {"title": "The actual title", "content": "The blogpost text."}
.
Is this a good or bad design? Justify your answer.
Sample answer
It's a bad design, because the resource in the body of the request contains no information about which account the blogpost should belong to. In HTTP, the body should contain the entire resource, so if one for example logs the URI, method and the body on the server-side and look at it later, one should be able to understand what the entire request is about.
Alice is probably thinking the account id in the access token can be used to figure out which account the blogpost should belong to, but access tokens should only be used for authorization, and not containing a part of a resource, so the body should still contain a value that indicates which account the blogpost should belong to, and the account id in the access token should only be used to figure out if the user is allowed to create a blogpost belonging to that account (e.g. all users may create a blogpost belonging to their own account, but admins may also create a blogpost belonging to someone else's account, so one can't blindly use the account id in the access token).
Marking guidelines
- 2 points for correct answer and access token VS body justification
Question 10 (3p)
Question
Describe the parts a JWT consists of. Then also explain why JWTs are secure to use (why a hacker can't fool a server by changing the data in the token or by creating her own token).
Sample answer
See for example Chapter 3.1 in the JWT Specification.
Marking guidelines
- 0.25 points for each (somewhat) correct name
- 0.50 points for each correct explanation
- only 0.25 points if explanation lacks details or contains errors, but to some degree is correct
- 0.75 points for explaining why they are secure
Question 11 (1p)
Question
When adding login functionality to a REST API, explain why it's usually not enough for the server to only send back an Access Token, but the server also needs to send back an ID Token.
Sample answer
When a user logs in, the client usually need to know information about the account the user logged in to, such as the account's id. Without that information, it would for example be impossible for the client to send requests and display information about resources belonging to that account, since the client can't identify the account.
Access Token are not designed to tell this information to the client, since they are only meant to be used for authorization. When implementing Access Tokens as JWT, it's possible for client to open up the Access Token and read information from it, but it's not something the client should rely on. For example, in the future, the server might change how it implements Access Token, so they are no longer implemented as JWT, and then the client code will no longer work.
So, instead, server usually send back an ID Token with the explicit purpose to contain information about the account the user logged in to, and is intended to be opened by the clients.
Marking guidelines
- 1 point for correct explanation
Question 12 (1p)
Question
Does an ID Token has to be implemented as a JWT? Justify your answer
Sample answer
Yes, the specification for OpenID Connect states:
The ID Token is represented as a JSON Web Token (JWT).
Marking guidelines
- 1 point for correct answer and valid justification
Question 13 (1p)
Question
If client-side JS code on a webpage tries to send an HTTP DELETE
request, will that always trigger a CORS pre-flight request? Justify your answer.
Sample answer
No, not always, not, for example, if the DELETE
request is sent to the server as the origin of the client-side JS, because then it's not a Cross-site request, and the Same-Origin Policy won't stop the request from being sent to begin with, so CORS is not needed.
Marking guidelines
- 1 point for correct answer and valid justification
Docker
Question 14 (1p)
Question
Explain what port mapping in Docker is, and give a practical example of when you need to use it.
Sample answer
All containers in Docker are running in an isolated environment, so no application on the host computer can communicate with an application in the container. By using port mapping, you can tell Docker that one port on the host computer should lead to one port in the container, and then the host computer can use this to communicate with an app in the container.
This is for example used when the container runs a web application, and you want to be able to send HTTP requests to it from a web browser running on the host computer.
Marking guidelines
- 0.5 points for what it is
- 0.5 points for practical example
Question 15 (1p)
Question
Explain what the Docker instruction COPY
can be used for, and explain when that instruction is executed.
Sample answer
As all Docker instructions, the COPY
instruction is executed when you build a Docker image. It instructs Docker to copy a file on the file system on the host computer to the file system that will exists in the container running the image.
Marking guidelines
- 0.5 points for what the instruction does
- 0.5 points for when it is executed
Scaling
Question 16 (1p)
Question
Explain how horizontal scaling works.
Sample answer
When a web application runs on a server and it receives more HTTP requests than it has time to handle, you can scale the application horizontally. That means you run the application on multiple servers behind a server that act as a load balancer. All clients send their HTTP requests to the load balancer, and the load balancer then forwards and distributes the HTTP requests among the servers running the web application, which carryout out the requests they receive and send back responses to the clients.
Marking guidelines
- 0.5 points for application running on multiple servers
- 0.25 points for explaining that the workload in distributed among the server
- 0.25 points for explaining how the workload is distributed (load balancer)
JavaScript
Question 17 (2p)
Question
The function getAccountByUsername()
should receive the username of an account as an argument, and it returns a promise that resolves to a JS object with information about the account with that username. If the account object can't be retrieved, the promise is rejected to a JS error object containing information about what went wrong.
The function getBlogpostsByAccount()
should receive an account object as an argument, and it returns a promise that resolves to a JS array with objects representing blogposts that account has created. If the blogposts can't be retrieved, the promise is rejected to a JS error object containing information about what went wrong.
Implement the function getAccountWithBlogpostsByUsername()
, that receives the username of an account as argument, and returns a promise that resolves to the account object with that username that also contains the property blogposts
that stores an array with all the blogposts created by that account.
If you get an error from getAccountByUsername()
or getBlogpostsByAccount()
, then your own promise should be rejected with the string "getDataError"
.
It is OK to use async
and await
in your implementation.
Sample answer
async function getAccountWithBlogpostsByUsername(username){
try {
const account = await getAccountByUsername(username)
account.blogposts = await getBlogpostsByAccount(account)
return account
}catch(error){
throw "getDataError"
}
}
Marking guidelines
- 2 points for a solution that is largely correct
- Point deductions for errors:
- -0.25 points for returning
{account, blogposts}
- -0.25 points for retuning error instead of throwing
- -0.25 points for not using
"getDataError"
as the rejected value
- -0.25 points for returning