How does Syscat implement its design principles?
- Use of a well-known protocol (HTTP) based on open standards means you can use existing tools and technologies to interact with it, with a familiar model of operation.
- API-first design provides flexibility of user interfaces, and means that all kinds of interactions can be automated.
- No more frustration from being unable to automate something you can do via the GUI.
- If you don't like the existing GUI (let's face it, this thing is crude) you can build your own.
- Addressing resources via a regular, predictable pattern makes it easy to build your own UIs and automation.
- There are no special cases waiting to catch you out. This does make some things a little clunky, but from my own experience this is a worthwhile trade-off.
- Minimal variety of APIs, enabled by the combination of the addressing scheme and the use of standard HTTP verbs (GET, POST, PUT and DELETE).
- Files are stored in the server's filesystem, with directories and filenames derived from each file's SHA-256 checksum, and their metadata is stored in the database as resources that can (mostly) be interacted with like any other.
- Uploading, downloading and deleting files can only be done via the Files API.
- Storing the metadata this way means you can enrich their meaning through relationships to other resources, starting with a link to the user account through which a given file was uploaded.
- Storing files according to their checksum prevents duplication.
- The IPAM API manages subnetting for you, automatically re-parenting subnets and addresses as you create and delete them.
- Relationships are defined with a set of constraints, to reflect real-world constraints.
- Cardinality indicates whether a relationship can be many-to-many, one-to-many, many-to-one, or one-to-one.
- E.g. a NIC (Network Interface Card) can only be installed in one device at a time, but a given device might contain many NICs.
- One-to-one relationships can be useful for optionally connecting a chunk of information about something, such as SNMP details for a discovered device, or IPTC data for a file containing a digital photograph.
- They're directional, reflecting the fact that they're often asymmetrical.
- Dependent relationships, from a parent resource to a child one, are marked as such.
- Cardinality indicates whether a relationship can be many-to-many, one-to-many, many-to-one, or one-to-one.
- Each resource has exactly one canonical path by which it can be updated.
- However, you can follow relationships from one resource to another, to any arbitrary distance. Your browser (or the webserver) will hit its character limit for URLs before Syscat runs out of breadcrumbs.
The naming/addressing scheme
URIs are dynamically validated against the schema, with an indefinitely-repeatable pattern of Resourcetype/uid/RELATIONSHIP
.
For example, if I wanted all the addresses on network interface eth0
on router`, I'd make this query:
curl http://192.0.2.1/raw/v1/Devices/router1/INTERFACES/NetworkInterfaces/eth0/ADDRESSES
That would return a JSON list of Ipv4Addresses
and Ipv6Addresses
objects (assuming the interface itself is configured for dual-stack operation).
If I just wanted the IPv6 addresses from that interface, I'd extend that URI to include the resourcetype at the end of that relationship:
curl http://192.0.2.1/raw/v1/Devices/router1/INTERFACES/NetworkInterfaces/eth0/ADDRESSES/Ipv6Addresses
Yes, those URIs are verbose. But after you're done screaming in horror, remember that this API is not designed for human interaction. It's designed for people to build automation tools against, and to build GUIs on; for those purposes it's more valuable to be consistent than it is to be concise.