JSON, XML & HTTP Methods – REST API Guide for Network Engineers
1. Why REST APIs Matter for Network Engineers
Modern network devices — Cisco IOS-XE, NX-OS, ACI, and SD-WAN controllers — expose REST APIs that allow engineers and automation tools to configure and monitor infrastructure programmatically. Instead of typing CLI commands line by line, a script can send a single HTTP request and change the configuration of dozens of devices simultaneously.
Understanding REST APIs requires three building blocks: JSON and XML (the data formats used to carry configuration and state information) and HTTP methods (the verbs that tell the server what to do with that data). These three topics appear directly on the CCNA exam under the Network Automation and Programmability domain.
Related pages: Controller-Based Networking | Postman & Ansible | Python Scripts for Networking | JSON, XML & YANG | NETCONF & RESTCONF Overview | REST API Overview | Network Automation Overview | Step-by-Step: Cisco RESTCONF | NETCONF ncclient Lab
2. JSON (JavaScript Object Notation)
What Is JSON?
JSON is a lightweight, text-based data-interchange format that represents structured data as key-value pairs and arrays. It is the dominant format for REST APIs because it is compact, human-readable, and natively supported by every modern programming language. See JSON, XML & YANG for the full data format comparison including YANG data models used by NETCONF and RESTCONF.
JSON Data Types
| Data Type | Example | Notes |
|---|---|---|
| String | "John" |
Always enclosed in double quotes |
| Number | 30, 3.14 |
Integer or floating-point; no quotes |
| Boolean | true, false |
Lowercase only; no quotes |
| Null | null |
Represents an empty or absent value |
| Object | {"key": "value"} |
Unordered collection of key-value pairs; keys must be strings |
| Array | ["a", "b", "c"] |
Ordered list of values; may contain mixed types |
JSON Syntax Example
{
"hostname": "R1",
"interface": "GigabitEthernet0/0",
"ip_address": "192.168.1.1",
"prefix_length": 24,
"enabled": true,
"description": null,
"tags": ["core", "uplink"]
}
Parsing and Generating JSON
Python: (see Python Scripts for Networking for full Python context)
import json
# Parse a JSON string into a Python dictionary
json_string = '{"hostname": "R1", "ip_address": "192.168.1.1"}'
data = json.loads(json_string)
print(data['hostname']) # Output: R1
print(data['ip_address']) # Output: 192.168.1.1
# Serialize a Python dictionary back to a JSON string
config = {"hostname": "R2", "ip_address": "10.0.0.1"}
json_output = json.dumps(config, indent=2)
print(json_output)
JavaScript:
// Parse JSON string into a JavaScript object
let jsonStr = '{"hostname": "R1", "ip_address": "192.168.1.1"}';
let obj = JSON.parse(jsonStr);
console.log(obj.hostname); // Output: R1
// Serialize a JavaScript object to a JSON string
let config = { hostname: "R2", ip_address: "10.0.0.1" };
let output = JSON.stringify(config, null, 2);
console.log(output);
JSON Use Cases in Networking
- Payload format for Cisco RESTCONF and DNA Center REST API calls (
Content-Type: application/json) - Ansible playbook variable files and output from network modules
- Configuration storage in tools like NSO (Network Services Orchestrator)
- Response body from
showcommands issued via NETCONF/RESTCONF
3. XML (eXtensible Markup Language)
What Is XML?
XML is a markup language that uses custom nested tags to represent hierarchical data in a platform-independent, self-describing format. It predates JSON and remains heavily used in enterprise systems and network management protocols such as NETCONF (which uses XML exclusively). See JSON, XML & YANG for the YANG data model layer that sits on top of XML in NETCONF.
XML Syntax Example
<?xml version="1.0" encoding="UTF-8"?>
<device>
<hostname>R1</hostname>
<interface name="GigabitEthernet0/0">
<ip_address>192.168.1.1</ip_address>
<prefix_length>24</prefix_length>
<enabled>true</enabled>
</interface>
<tags>
<tag>core</tag>
<tag>uplink</tag>
</tags>
</device>
XML Parsing in Python
import xml.etree.ElementTree as ET
xml_string = """
<device>
<hostname>R1</hostname>
<interface name="GigabitEthernet0/0">
<ip_address>192.168.1.1</ip_address>
</interface>
</device>
"""
root = ET.fromstring(xml_string)
print(root.find('hostname').text) # Output: R1
print(root.find('interface/ip_address').text) # Output: 192.168.1.1
print(root.find('interface').get('name')) # Output: GigabitEthernet0/0
XML Advantages and Disadvantages
| Advantages | Disadvantages |
|---|---|
|
|
4. JSON vs. XML – Side-by-Side Comparison
| Feature | JSON | XML |
|---|---|---|
| Syntax style | Key-value pairs and arrays with { } and [ ] |
Opening and closing tags: <tag>value</tag> |
| Verbosity | Compact — each key appears once | Verbose — every field name appears twice (open + close tag) |
| Data types | Natively supports string, number, boolean, null, object, array | All values are text; types inferred by schema or application |
| Attributes | Not supported — all data in key-value pairs | Elements can carry attributes: <tag attr="v"> |
| Comments | Not supported in the JSON spec | Supported: <!-- comment --> |
| Schema validation | JSON Schema (draft standard) | XSD (XML Schema Definition) — mature and widely supported |
| Primary use today | REST APIs, web applications, Ansible, RESTCONF | NETCONF, SOAP web services, enterprise legacy systems |
| Human readability | More readable for most developers | Readable but becomes unwieldy for large documents |
See JSON, XML & YANG for the complete reference including YANG data models.
5. HTTP Methods – Overview
HTTP (HyperText Transfer Protocol) is the foundation of data communication on the web and in REST APIs. A client sends a request (containing a method, URL, headers, and optional body) and the server returns a response (containing a status code, headers, and optional body).
Two important properties define how HTTP methods behave:
- Safe: The method does not modify server state. GET and HEAD are safe.
- Idempotent: Calling the method multiple times produces the same result as calling it once. GET, HEAD, PUT, and DELETE are idempotent. POST is neither safe nor idempotent.
HTTP Request structure:
METHOD /path HTTP/1.1
Host: api.example.com
Content-Type: application/json
Authorization: Bearer <token>
{ "key": "value" } ← body (not used with GET/DELETE)
HTTP Response structure:
HTTP/1.1 200 OK
Content-Type: application/json
{ "id": 1, "name": "R1" }
See REST API Overview for the full architectural context, and Postman & Ansible for tools used to send these requests.
6. The Five Core HTTP Methods
GET — Retrieve Data
- Purpose: Read a resource without modifying it
- Safe and idempotent; multiple identical requests return the same result
- Parameters sent in the URL query string, never in the body
- Responses may be cached by browsers and proxies
GET /api/devices/1 HTTP/1.1
Host: api.example.com
Accept: application/json
POST — Create a New Resource
- Purpose: Submit data to create a new resource; server determines the resource URI
- Not idempotent: sending the same POST twice typically creates two separate resources
- Data sent in the request body
- Returns
201 Createdwith aLocationheader pointing to the new resource
POST /api/devices HTTP/1.1
Host: api.example.com
Content-Type: application/json
{
"hostname": "R3",
"ip_address": "10.0.0.3",
"type": "router"
}
PUT — Replace / Upsert a Resource
- Purpose: Replace an entire resource at a known URI, or create it if it does not exist (upsert)
- Idempotent: repeating the same PUT produces the same server state
- The body must contain the complete new representation of the resource; omitted fields are removed
PUT /api/devices/1 HTTP/1.1
Host: api.example.com
Content-Type: application/json
{
"hostname": "R1-updated",
"ip_address": "192.168.1.1",
"type": "router"
}
PATCH — Partial Update
- Purpose: Apply a partial modification to an existing resource — only the supplied fields are changed
- More efficient than PUT when only one or two fields need updating
- Not guaranteed to be idempotent (depends on implementation)
PATCH /api/devices/1 HTTP/1.1
Host: api.example.com
Content-Type: application/json
{
"hostname": "R1-patched"
}
<!-- Only hostname is updated; all other fields are unchanged -->
DELETE — Remove a Resource
- Purpose: Delete the specified resource
- Idempotent: deleting an already-deleted resource returns
404 Not Foundor204 No Content— the end state (resource gone) is the same - Usually no request body
DELETE /api/devices/1 HTTP/1.1
Host: api.example.com
7. HTTP Methods Comparison Table
| Method | CRUD Action | Idempotent? | Safe? | Request Body? | Typical Response Code | Networking Example |
|---|---|---|---|---|---|---|
| GET | Read | Yes | Yes | No | 200 OK | Retrieve interface status from RESTCONF |
| POST | Create | No | No | Yes | 201 Created | Add a new VLAN via Cisco DNA Center API |
| PUT | Replace / Upsert | Yes | No | Yes (full resource) | 200 OK / 201 Created | Replace full interface configuration |
| PATCH | Partial Update | Usually Yes | No | Yes (partial resource) | 200 OK | Change only the description of an interface |
| DELETE | Delete | Yes | No | Usually No | 204 No Content | Remove a static route via RESTCONF |
| HEAD | Read (headers only) | Yes | Yes | No | 200 OK | Check if a resource exists without downloading the body |
8. HTTP Status Codes
Every HTTP response includes a three-digit status code that tells the client what happened. They are grouped into five classes:
| Code | Name | Typical Cause | Common HTTP Method |
|---|---|---|---|
| 200 | OK | Request succeeded; body contains the requested data | GET, PUT, PATCH |
| 201 | Created | Resource successfully created; Location header gives its URI | POST |
| 204 | No Content | Request succeeded; no response body (e.g., after a DELETE) | DELETE, PUT |
| 400 | Bad Request | Malformed JSON/XML in request body; missing required field | POST, PUT, PATCH |
| 401 | Unauthorized | Missing or invalid authentication token / credentials. See AAA Authentication Methods. | Any |
| 403 | Forbidden | Authenticated but not authorised for this resource. See AAA Authentication Methods. | Any |
| 404 | Not Found | Requested resource does not exist at the given URI | GET, DELETE, PUT |
| 405 | Method Not Allowed | HTTP method not supported on this endpoint (e.g., DELETE on a read-only resource) | Any |
| 500 | Internal Server Error | Unhandled exception or bug on the server side | Any |
| 503 | Service Unavailable | Server overloaded or down for maintenance | Any |
9. RESTful API Principles
A REST (Representational State Transfer) API follows six architectural constraints that make it scalable, stateless, and interoperable. See REST API Overview for the full architectural context.
| Constraint | What It Means in Practice |
|---|---|
| Stateless | Every request contains all information the server needs; the server stores no session state between requests |
| Client–Server | The client (e.g., Ansible, Python script) and server (e.g., Cisco DNA Center) are independent; they communicate only through the API contract |
| Uniform Interface | Resources identified by URIs; HTTP methods define the action; standard status codes; content negotiation via headers |
| Cacheable | Responses indicate whether they can be cached; safe methods (GET, HEAD) are typically cacheable |
| Layered System | Clients do not need to know if they are talking to the real server or an intermediary (proxy, load balancer, API gateway) |
| Code on Demand (optional) | Server may send executable code (e.g., JavaScript); rarely used in network APIs |
10. Hands-On: Making HTTP Requests
Python — requests Library
See Python Scripts for Networking for full Python syntax context and Python Netmiko Lab for device-specific automation.
import requests
import json
BASE_URL = 'https://jsonplaceholder.typicode.com'
HEADERS = {'Content-Type': 'application/json'}
# GET — retrieve a resource
response = requests.get(f'{BASE_URL}/users/1')
print(response.status_code) # 200
print(response.json()) # {'id': 1, 'name': 'Leanne Graham', ...}
# POST — create a new resource
payload = {"name": "John", "username": "john123", "email": "john@example.com"}
response = requests.post(f'{BASE_URL}/users', json=payload, headers=HEADERS)
print(response.status_code) # 201
print(response.json())
# PUT — replace a resource
payload = {"name": "John Updated", "username": "john_updated"}
response = requests.put(f'{BASE_URL}/users/1', json=payload, headers=HEADERS)
print(response.status_code) # 200
# PATCH — partial update
payload = {"name": "John Patched"}
response = requests.patch(f'{BASE_URL}/users/1', json=payload, headers=HEADERS)
print(response.status_code) # 200
# DELETE — remove a resource
response = requests.delete(f'{BASE_URL}/users/1')
print(response.status_code) # 200 or 204
JavaScript — Fetch API
const BASE_URL = 'https://jsonplaceholder.typicode.com';
const HEADERS = { 'Content-Type': 'application/json' };
// GET
fetch(`${BASE_URL}/users/1`)
.then(r => r.json())
.then(data => console.log(data));
// POST
fetch(`${BASE_URL}/users`, {
method: 'POST',
headers: HEADERS,
body: JSON.stringify({ name: "John", username: "john123" })
})
.then(r => r.json())
.then(data => console.log(data));
// PUT
fetch(`${BASE_URL}/users/1`, {
method: 'PUT',
headers: HEADERS,
body: JSON.stringify({ name: "John Updated", username: "john_updated" })
})
.then(r => r.json())
.then(data => console.log(data));
// DELETE
fetch(`${BASE_URL}/users/1`, { method: 'DELETE' })
.then(r => console.log(r.status)); // 200
11. Security Considerations
| Concern | Risk | Best Practice |
|---|---|---|
| Data in URL (GET) | Query parameters visible in server logs, browser history, and proxy logs | Never send sensitive data (passwords, tokens) as URL parameters |
| Unencrypted transport | HTTP (port 80) exposes request body and headers to any on-path observer | Always use HTTPS (TLS) for API calls; reject HTTP connections to management APIs. See SSH & Telnet Security. |
| Missing authentication | Unauthenticated API calls allow any client to read or modify resources | Require authentication: API keys, OAuth 2.0 tokens, or certificate-based mutual TLS. See AAA Authentication Methods. |
| Overly permissive methods | Exposing DELETE or PUT on endpoints that should be read-only allows data deletion/modification | Return 405 Method Not Allowed for unsupported methods; apply role-based access control |
| CSRF (Cross-Site Request Forgery) | A malicious web page tricks an authenticated user’s browser into making state-changing API calls | Use CSRF tokens on state-changing methods (POST/PUT/DELETE); validate Origin header |
12. Key Points & CCNA Exam Tips
- JSON is the dominant REST API format: compact, human-readable, natively supported; six data types: string, number, boolean, null, object, array. See JSON, XML & YANG.
- XML uses custom tags and is required by NETCONF; more verbose than JSON but supports attributes and mature schema validation (XSD)
- GET = read; safe and idempotent; parameters in URL; response may be cached
- POST = create; neither safe nor idempotent; data in body; returns
201 Created - PUT = replace entire resource at known URI; idempotent; must send full resource in body
- PATCH = partial update; only changed fields in body; more efficient than PUT for small changes
- DELETE = remove resource; idempotent; typically no body; returns
204 No Content - Idempotent = repeating the same operation produces the same result: GET, HEAD, PUT, DELETE are idempotent; POST is not
- Safe = does not modify server state: only GET and HEAD are safe
- HTTP status code classes: 2xx = success; 4xx = client error; 5xx = server error; know 200, 201, 204, 400, 401, 403, 404, 500
- REST APIs are stateless: every request must carry all required information; no session stored on the server. See REST API Overview.
- Always use HTTPS for API calls; never send credentials or sensitive config in URL query strings. See SSH & Telnet Security.
- Authentication for APIs: API keys, OAuth 2.0, or certificate-based TLS. See AAA Authentication Methods.
- Tools used in the CCNA exam context: Postman (GUI API testing), curl (command-line), Python
requests, JavaScriptfetch. See Postman & Ansible. - Cisco-specific: RESTCONF uses HTTP methods with JSON/XML payloads to configure IOS-XE devices. Try the Cisco RESTCONF Lab.