عناوين URL ومعاملات الاستعلام
في هذا الدرس 11 موضوعات
هذا الدرس متاح حاليًا باللغة الإنجليزية فقط، ولم تُنشر نسخته العربية بعد.
Lesson Overview
The order slip needs an address: which restaurant, which counter, and which dish. In HTTP that address is the URL. You met the parts of a URL in BEG-003; this lesson works with them the way a backend developer does, asking of each part: who reads it, and what is it for?
Two pieces matter most when you design and read APIs. The path names the resource (/books/7). The query parameters after the ? filter, sort, or tune the answer (?author=herbert&page=2). Learning to keep those two jobs apart makes URLs predictable, and lets you read any address you see in the browser's Network tab.
This lesson builds on lesson 1 (the request target), lesson 2 (nouns in paths), and BEG-003 (scheme, host, port, fragment).
Learning Objectives
By the end of this lesson you will be able to:
- Split a URL into scheme, host, port, path, query, and fragment.
- Read a query string as
name=valuepairs joined by&. - Explain which part identifies the resource and which part refines the request.
- Explain that the fragment is handled by the browser and is not sent to the server.
- Explain why special characters in a URL are written in an escaped form such as
%20. - Extract the parts of a URL in Java with
java.net.URI(a preview of a standard JDK class).
Written Explanation
The parts
https://api.example.com:8443/books/7?author=herbert&page=2#top
| | | | | |
scheme host port path query fragment| Part | Value | Job |
|---|---|---|
| Scheme | https | Which protocol to use |
| Host | api.example.com | Which server (a domain name or an IP address) |
| Port | 8443 | Which door on that server; usually omitted |
| Path | /books/7 | Which resource on the server |
| Query | author=herbert&page=2 | Extra key/value details for the request |
| Fragment | top | A position inside the resource, used by the browser |
MDN's description: the port may be left out when the standard ports are used (80 for HTTP, 443 for HTTPS), the path is these days usually handled by the server rather than being a literal file path, and query parameters are key/value pairs separated by &, which the server decides how to interpret.
The path identifies the resource
A good path is a noun, in the style of lesson 2: /books is the collection, /books/7 is one item, and /books/7/reviews could be the reviews of that item. Two different paths are two different resources. Changing the path changes what you are talking about.
The query refines the request
After a ?, the query holds name=value pairs, separated by &:
/books?author=herbert&page=2This still means "the books collection" but asks for those by one author, second page. Query parameters usually express optional choices: filtering (author=herbert), sorting (sort=title), paging (page=2), and similar. Leave them off and you get the default behaviour.
A rule of thumb: if the thing is which resource, it belongs in the path; if it is how you want to see it, it belongs in the query. /books/7 is book 7. /books?year=1965 is the books from 1965. The split is a convention that servers follow, not something the protocol enforces.
The fragment stays in the browser
The part after # points to a place inside the resource, such as a heading on a page. MDN states that the fragment is never sent to the server with the request: the browser handles it locally. So a server cannot read the fragment, and you must not rely on it for data your backend needs. In the request line you saw in lesson 1, only the path and query appear:
GET /books?author=herbert&page=2 HTTP/1.1
Host: api.example.comSpecial characters and escaping
URLs can only contain a limited set of characters. A space, an & inside a value, or non-Latin text must be written in an escaped form, called percent-encoding, where a character becomes % plus two hexadecimal digits. A space is %20: ?q=science%20fiction carries the value "science fiction". Browsers and libraries usually do this for you, and the server decodes it. Java's URI shows both forms: the raw one keeps %20, the decoded one shows a space (see Example 3). (The JDK documentation and a test run confirm this; the full list of reserved characters is beyond this lesson.)
Reading URLs in the wild
Real-world URLs can look intimidating: a long address from a shopping site may have a dozen query parameters with cryptic names such as ref= or utm_source=. Do not panic. Read left to right: scheme, host, then the path up to the first ?, then each name=value pair between & signs, and finally anything after #. Most of the length is usually tracking or display options. What matters to the backend is the path plus the parameters the server actually reads, and a server may simply ignore parameters it does not know. A port number in the middle (:8080, :3000) is common while a service is being developed on your own machine, which is why you will often type addresses like that during the Java web modules.
URL versus URI
You will see both words. A URI is a general identifier for a resource; a URL is a URI that also says where and how to get it. For daily work they are used almost interchangeably, and Java's class is called URI.
Examples
Example 1: Split a URL (simple)
https://shop.example.com/books/7?lang=en#reviews
- Scheme:
https - Host:
shop.example.com - Port: none written (HTTPS default, 443)
- Path:
/books/7 - Query:
lang=en - Fragment:
reviews(not sent to the server)
Example 2: Path or query? (practical)
You are designing endpoints for a library API.
| Need | URL | Why |
|---|---|---|
| Show member 12 | /members/12 | Identifies one resource: path |
| Show members in the city of Jeddah | /members?city=Jeddah | A filter on the collection: query |
| Second page, 20 per page | /members?page=2&size=20 | How to slice the result: query |
| Loans of member 12 | /members/12/loans | A sub-resource belonging to the member: path |
| Overdue loans of member 12 | /members/12/loans?status=overdue | Resource in the path, filter in the query |
Notice how every row reads naturally as "which thing, then how to look at it". The names (page, size, status) are choices of the API designer.
Example 3: Pick a URL apart in Java (realistic)
java.net.URI is a ready-made JDK class that parses a URL. It is a preview here: you only need to know how to construct it and call getters.
import java.net.URI;
public class L06 {
public static void main(String[] args) {
URI u = URI.create("https://api.example.com:8443/books/7?author=herbert&page=2#top");
System.out.println("scheme = " + u.getScheme());
System.out.println("host = " + u.getHost());
System.out.println("port = " + u.getPort());
System.out.println("path = " + u.getPath());
System.out.println("query = " + u.getRawQuery());
System.out.println("fragment = " + u.getFragment());
for (String pair : u.getRawQuery().split("&")) {
String[] kv = pair.split("=", 2);
System.out.println(" " + kv[0] + " = " + kv[1]);
}
URI plain = URI.create("https://api.example.com/books");
System.out.println("no port -> " + plain.getPort());
}
}Output (compiled and run with JDK 21):
scheme = https
host = api.example.com
port = 8443
path = /books/7
query = author=herbert&page=2
fragment = top
author = herbert
page = 2
no port -> -1Per the JDK documentation, getPort() returns -1 when the URI has no port, and getRawQuery() returns null when there is no query (so split on it would throw; check first). A second run shows how a request target is built from a URL, and how escaping looks:
URI u = URI.create("https://api.example.com/books?author=herbert&page=2#top");
String target = u.getRawPath() + "?" + u.getRawQuery();
System.out.println("GET " + target + " HTTP/1.1");
System.out.println("Host: " + u.getHost());
URI s = URI.create("https://shop.example.com/search?q=science%20fiction");
System.out.println(s.getRawQuery()); // raw
System.out.println(s.getQuery()); // decodedGET /books?author=herbert&page=2 HTTP/1.1
Host: api.example.com
q=science%20fiction
q=science fictionThe fragment top does not appear in the request target, matching the rule above. URI.create is meant for text known to be valid: on an illegal string it throws IllegalArgumentException, so for user input the JDK recommends new URI(...), which throws a checked URISyntaxException that you handle.
Backend Insight
The URL structure is the public face of your backend. Frameworks you will use later let you attach Java methods to paths and read query parameters as method arguments. Getting the split right pays off: clients can guess /books/7 after seeing /books, and your logs and monitoring group traffic by path.
Remember that everything in a URL is visible: it appears in browser history, server logs, and the address bar. Never put passwords, tokens, or other secrets in a path or query string. Send credentials in headers over HTTPS instead (lesson 4).
Query parameters also arrive as text, even when they look like numbers. page=2 is the string "2" until your code converts it, and the conversion can fail: page=abc should lead to a 400, not a crash with a 500 (lesson 3). Treat missing parameters as normal and give them defaults.
Common Mistakes
Mistake 1: Putting verbs or filters in the wrong place
- Incorrect:
/getBooksByAuthor/herbert. - Correct:
/books?author=herbert.
Mistake 2: Expecting the server to see the fragment
- Incorrect: building a feature that reads
#sectionon the backend. - Correct: the fragment never reaches the server; put data you need in the path or query.
Mistake 3: Putting secrets in the URL
- Incorrect:
/login?user=ana&password=secret. - Correct: send credentials in the request body or an
Authorizationheader over HTTPS. URLs are logged and stored in history.
Mistake 4: Forgetting that query values are text, and need escaping
- Incorrect:
?q=science fiction&xwith a raw space, or treatingpage=2as already anint. - Correct: write
?q=science%20fictionand convertpageyourself, handling bad input.
Exercises
Level A: Foundation
A1. Split http://library.example.org:8080/loans/5?status=open#details into scheme, host, port, path, query, and fragment.
A2. In /movies?genre=drama&year=2016, how many query parameters are there, and what are they?
A3. Is the fragment sent to the server?
Level B: Application
B1. Decide path or query for each: movie 42; movies of genre drama; the cast of movie 42; the third page of results.
B2. Write the request line (method, target, version) a browser sends for https://api.example.com/movies?genre=drama#cast.
B3. A colleague designs GET /search?q=rock&password=abc123. Name two problems.
Level C: Challenge
C1. Write a Java snippet that, given the string https://api.example.com/books?author=herbert&page=2, prints the value of the page parameter as an int plus 1. Say what should happen if the query is missing.
C2. A user searches for "fish & chips". Explain why the raw text ?q=fish & chips breaks the query and how it should be written.
أظهر الحلول
A1. Scheme http; host library.example.org; port 8080; path /loans/5; query status=open; fragment details.
A2. Two: genre=drama and year=2016.
A3. No. The browser keeps it.
B1. /movies/42 (path); /movies?genre=drama (query); /movies/42/cast (path, a sub-resource); /movies?page=3 (query).
B2.
GET /movies?genre=drama HTTP/1.1The fragment #cast is not sent; the Host: api.example.com header goes below.
C1.
URI u = URI.create("https://api.example.com/books?author=herbert&page=2");
String q = u.getRawQuery();
if (q == null) {
System.out.println("no query, use defaults");
} else {
for (String pair : q.split("&")) {
String[] kv = pair.split("=", 2);
if (kv[0].equals("page")) {
System.out.println(Integer.parseInt(kv[1]) + 1);
}
}
}This prints 3 (compiled and run). If the query is missing, getRawQuery() returns null, so the null check chooses defaults. If page is not a number, Integer.parseInt throws NumberFormatException, which a backend turns into a 400.
C2. The & is the separator between parameters, so the server would read q=fish and then a parameter named chips; the space is not allowed raw either. Write ?q=fish%20%26%20chips, where %26 is the escaped & and %20 is the escaped space. (%26 for & is standard percent-encoding; I did not run this one.)
Mini Challenge
Take a URL from a real site you use (a search result or a product page) and copy it as text, removing anything that looks personal, like tokens or ids you do not want to share. Split it into the six parts in a table, mark which parts reach the server, and list each query parameter with a guess of what it does. Then redesign the same request as a clean API URL, with a noun path and query for the refinements.
Check your work: the table has scheme, host, port (or "default"), path, query, and fragment; the fragment is marked as not sent; your redesigned URL has no verbs and no secrets.
Summary & Next Lesson
Key takeaways
- A URL has a scheme, host, optional port, path, optional query, and optional fragment.
- The path identifies the resource; query parameters (
name=valuejoined by&) refine it. - The fragment after
#is for the browser and is never sent to the server. - Special characters are percent-encoded, such as
%20for a space. - URLs are visible in logs and history, so never put secrets in them.
Next lesson
The next lesson, "Demo: reading real HTTP traffic in the browser", puts every part from this module to work on a real site using the Network tab, in preparation for the lab.
Self-check
- In
/books?page=2, what ispage=2? - Which part of a URL identifies the resource?
- Is the fragment sent to the server?
- How is a space written inside a URL?
- Why should a token never be put in a query string?
أظهر الإجابات
- A query parameter: name
page, value2. - The path.
- No.
- As
%20(percent-encoding). - URLs show up in browser history and logs, so the token could leak.
References
- MDN: What is a URL?. Supports the parts of a URL, default ports 80 and 443, the path, the
&-separated query, and that the fragment is never sent to the server. - Java SE 21 API: java.net.URI. Supports
getPort()returning-1,getRawQuery()andgetFragment()returningnullwhen absent, raw versus decoded forms, andURI.createthrowingIllegalArgumentException.
Not verified from a source: the URL-versus-URI wording is simplified, and the advice about secrets in URLs is general security practice.
التطبيق
طبّق هذا الدرس بمختبر الوحدة وتمارينها واختبارها.
تعليم الدرس كمكتمل اختياري ويمكنك التراجع عنه في أي وقت. يبقى تقدمك محفوظًا في هذا المتصفح.