What's the difference between declarative syntax and encapsulation?
They're orthogonal.

In declarative programming, you describe what would count as an acceptable solution, without necessarily describing how to find it.  For instance, a declarative program might have rules like "if you want to install the package gcc, you must have first installed the binutils and cpp packages" and "if you want to install the binutils package, you must have first installed coreutils".  It's up to the platform to figure out a way to meet all of these constraints.

Encapsulation refers to protections that prevent the client of an API from tampering with the internal state of the service that implements the API.   Nothing here says the API has to be declarative in nature.  You could have a API that is more declarative in nature (e.g., the client provides some constraints, and the service figures out how to meet them), or you could have an API that is more operational in nature (e.g., the client specifies what actions should be performed, rather than listing the desired goal and leaving it to the service to figure out what actions will accomplish that goal).

So, you can have an encapsulated API that is not declarative in nature.



To elaborate: invoking an API is not necessarily declarative in nature.  You can design APIs that are declarative in feel; and you can also APIs that are operational in feel.  Not all APIs will be declarative.  For example:


A declarative API might let you give it some rules/constraints, and then specify the goal (I want gcc to be installed), and then let the service infer a sequence of actions that will achieve your goal (a sequence of packages to install, and what order to install them in).  For example, the client might call findWayToInstall("gcc"), and the service comes up with a sequence of packages to install that ends with gcc installed -- that'd be a declarative API.
An operational API might let you repeatedly give it an action to perform (e.g., you repeatedly invoke installPackage(); this succeeds if you've met all the prereqs, and it's up to you to identify a valid sequence of packages that ends with gcc installed).  For example, the client might call installPackage("coreutils") then installPackage("binutils") then installPackage("cpp") then installPackage("gcc"), and if this sequence of operations meets all of the prerequisites, it ends with gcc installed.  With this API it is the caller's responsibility to identify a sequence of actions that ends with gcc installed.  Thus, this kind of API is more operational than declarative in nature.


Of course, declarative vs operational are just concepts to help us talk about properties of programming languages and APIs.  There's no hard, bright line between them.  It's not black-and-white; there's a spectrum.  But they are useful concepts nonetheless.