2021-03-17 15:58:17 +00:00
|
|
|
# Significant patterns
|
|
|
|
|
ui: Don't default to the default namespace, use the token default namespace instead (#10503)
The default namespace, and the tokens default namespace (or its origin namespace) is slightly more complicated than other things we deal with in the UI, there's plenty of info/docs on this that I've added in this PR.
Previously:
When a namespace was not specified in the URL, we used to default to the default namespace. When you logged in using a token we automatically forward you the namespace URL that your token originates from, so you are then using the namespace for your token by default. You can of course then edit the URL to remove the namespace portion, or perhaps revisit the UI at the root path with you token already set. In these latter cases we would show you information from the default namespace. So if you had no namespace segment/portion in the URL, we would assume default, perform actions against the default namespace and highlight the default namespace in the namespace selector menu. If you wanted to perform actions in your tokens origin namespace you would have to manually select it from the namespace selector menu.
This PR:
Now, when you have no namespace segment/portion in the URL, we use the token's origin namespace instead (and if you don't have a token, we then use the default namespace like it was previously)
Notes/thoughts:
I originally thought we were showing an incorrectly selected namespace in the namespace selector, but it also matched up with what we were doing with the API, so it was in fact correct. The issue was more that we weren't selecting the origin namespace of the token for the user when a namespace segment was omitted from the URL. Seeing as we automatically forward you to the tokens origin namespace when you log in, and we were correctly showing the namespace we were acting on when you had no namespace segment in the URL (in the previous case default), I'm not entirely sure how much of an issue this actually was.
This characteristic of namespace+token+namespace is a little weird and its easy to miss a subtlety or two so I tried to add some documentation in here for future me/someone else (including some in depth code comment around one of the API endpoints where this is very subtle and very hard to miss). I'm not the greatest at words, so would be great to get some edits there if it doesn't seem clear to folks.
The fact that we used to save your previous datacenter and namespace into local storage for reasons also meant the interaction here was slightly more complicated than it needed to be, so whilst we were here we rejigged things slightly to satisfy said reasons still but not use local storage (we try and grab the info from higher up). A lot of the related code here is from before we had our Routlets which I think could probably make all of this a lot less complicated, but I didn't want to do a wholesale replacement in this PR, we can save that for a separate PR on its own at some point.
2021-07-07 10:46:41 +00:00
|
|
|
## Ember specific
|
|
|
|
|
2021-03-17 15:58:17 +00:00
|
|
|
The Consul UI tries to follow typical conventional ember but differs
|
|
|
|
significantly in several places:
|
|
|
|
|
ui: Don't default to the default namespace, use the token default namespace instead (#10503)
The default namespace, and the tokens default namespace (or its origin namespace) is slightly more complicated than other things we deal with in the UI, there's plenty of info/docs on this that I've added in this PR.
Previously:
When a namespace was not specified in the URL, we used to default to the default namespace. When you logged in using a token we automatically forward you the namespace URL that your token originates from, so you are then using the namespace for your token by default. You can of course then edit the URL to remove the namespace portion, or perhaps revisit the UI at the root path with you token already set. In these latter cases we would show you information from the default namespace. So if you had no namespace segment/portion in the URL, we would assume default, perform actions against the default namespace and highlight the default namespace in the namespace selector menu. If you wanted to perform actions in your tokens origin namespace you would have to manually select it from the namespace selector menu.
This PR:
Now, when you have no namespace segment/portion in the URL, we use the token's origin namespace instead (and if you don't have a token, we then use the default namespace like it was previously)
Notes/thoughts:
I originally thought we were showing an incorrectly selected namespace in the namespace selector, but it also matched up with what we were doing with the API, so it was in fact correct. The issue was more that we weren't selecting the origin namespace of the token for the user when a namespace segment was omitted from the URL. Seeing as we automatically forward you to the tokens origin namespace when you log in, and we were correctly showing the namespace we were acting on when you had no namespace segment in the URL (in the previous case default), I'm not entirely sure how much of an issue this actually was.
This characteristic of namespace+token+namespace is a little weird and its easy to miss a subtlety or two so I tried to add some documentation in here for future me/someone else (including some in depth code comment around one of the API endpoints where this is very subtle and very hard to miss). I'm not the greatest at words, so would be great to get some edits there if it doesn't seem clear to folks.
The fact that we used to save your previous datacenter and namespace into local storage for reasons also meant the interaction here was slightly more complicated than it needed to be, so whilst we were here we rejigged things slightly to satisfy said reasons still but not use local storage (we try and grab the info from higher up). A lot of the related code here is from before we had our Routlets which I think could probably make all of this a lot less complicated, but I didn't want to do a wholesale replacement in this PR, we can save that for a separate PR on its own at some point.
2021-07-07 10:46:41 +00:00
|
|
|
### Routing
|
2021-03-17 15:58:17 +00:00
|
|
|
|
|
|
|
We use a declarative configuration format for our routing rather than Ember's
|
|
|
|
DSL. The format is closely modeled on Ember's DSL and if you need to generate
|
|
|
|
Ember's DSL from this for some reason you can use one of our Debug Utilities
|
|
|
|
to do this.
|
|
|
|
|
ui: Don't default to the default namespace, use the token default namespace instead (#10503)
The default namespace, and the tokens default namespace (or its origin namespace) is slightly more complicated than other things we deal with in the UI, there's plenty of info/docs on this that I've added in this PR.
Previously:
When a namespace was not specified in the URL, we used to default to the default namespace. When you logged in using a token we automatically forward you the namespace URL that your token originates from, so you are then using the namespace for your token by default. You can of course then edit the URL to remove the namespace portion, or perhaps revisit the UI at the root path with you token already set. In these latter cases we would show you information from the default namespace. So if you had no namespace segment/portion in the URL, we would assume default, perform actions against the default namespace and highlight the default namespace in the namespace selector menu. If you wanted to perform actions in your tokens origin namespace you would have to manually select it from the namespace selector menu.
This PR:
Now, when you have no namespace segment/portion in the URL, we use the token's origin namespace instead (and if you don't have a token, we then use the default namespace like it was previously)
Notes/thoughts:
I originally thought we were showing an incorrectly selected namespace in the namespace selector, but it also matched up with what we were doing with the API, so it was in fact correct. The issue was more that we weren't selecting the origin namespace of the token for the user when a namespace segment was omitted from the URL. Seeing as we automatically forward you to the tokens origin namespace when you log in, and we were correctly showing the namespace we were acting on when you had no namespace segment in the URL (in the previous case default), I'm not entirely sure how much of an issue this actually was.
This characteristic of namespace+token+namespace is a little weird and its easy to miss a subtlety or two so I tried to add some documentation in here for future me/someone else (including some in depth code comment around one of the API endpoints where this is very subtle and very hard to miss). I'm not the greatest at words, so would be great to get some edits there if it doesn't seem clear to folks.
The fact that we used to save your previous datacenter and namespace into local storage for reasons also meant the interaction here was slightly more complicated than it needed to be, so whilst we were here we rejigged things slightly to satisfy said reasons still but not use local storage (we try and grab the info from higher up). A lot of the related code here is from before we had our Routlets which I think could probably make all of this a lot less complicated, but I didn't want to do a wholesale replacement in this PR, we can save that for a separate PR on its own at some point.
2021-07-07 10:46:41 +00:00
|
|
|
### Routes
|
2021-03-17 15:58:17 +00:00
|
|
|
|
|
|
|
We use a specific BaseRoute as a parent Route for **all** our Routes. This contains project wide
|
|
|
|
functionality for several important additions. If you use the normal `ember
|
|
|
|
generate route route-name` generator this inheritance is automatically added
|
|
|
|
for you. If you don't use the generator please ensure you use:
|
|
|
|
|
|
|
|
```js
|
|
|
|
import Route from 'consul-ui/routing/route';
|
|
|
|
export default class NameOfRoute extends Route {}
|
|
|
|
```
|
|
|
|
|
|
|
|
Query parameters should be added to Routes, not Controllers. If a controller
|
|
|
|
has no query parameters configured they are copied over from the Route.
|
|
|
|
Preferably we don't use Controllers, but this doesn't mean you shouldn't if
|
|
|
|
you need to.
|
|
|
|
|
ui: Don't default to the default namespace, use the token default namespace instead (#10503)
The default namespace, and the tokens default namespace (or its origin namespace) is slightly more complicated than other things we deal with in the UI, there's plenty of info/docs on this that I've added in this PR.
Previously:
When a namespace was not specified in the URL, we used to default to the default namespace. When you logged in using a token we automatically forward you the namespace URL that your token originates from, so you are then using the namespace for your token by default. You can of course then edit the URL to remove the namespace portion, or perhaps revisit the UI at the root path with you token already set. In these latter cases we would show you information from the default namespace. So if you had no namespace segment/portion in the URL, we would assume default, perform actions against the default namespace and highlight the default namespace in the namespace selector menu. If you wanted to perform actions in your tokens origin namespace you would have to manually select it from the namespace selector menu.
This PR:
Now, when you have no namespace segment/portion in the URL, we use the token's origin namespace instead (and if you don't have a token, we then use the default namespace like it was previously)
Notes/thoughts:
I originally thought we were showing an incorrectly selected namespace in the namespace selector, but it also matched up with what we were doing with the API, so it was in fact correct. The issue was more that we weren't selecting the origin namespace of the token for the user when a namespace segment was omitted from the URL. Seeing as we automatically forward you to the tokens origin namespace when you log in, and we were correctly showing the namespace we were acting on when you had no namespace segment in the URL (in the previous case default), I'm not entirely sure how much of an issue this actually was.
This characteristic of namespace+token+namespace is a little weird and its easy to miss a subtlety or two so I tried to add some documentation in here for future me/someone else (including some in depth code comment around one of the API endpoints where this is very subtle and very hard to miss). I'm not the greatest at words, so would be great to get some edits there if it doesn't seem clear to folks.
The fact that we used to save your previous datacenter and namespace into local storage for reasons also meant the interaction here was slightly more complicated than it needed to be, so whilst we were here we rejigged things slightly to satisfy said reasons still but not use local storage (we try and grab the info from higher up). A lot of the related code here is from before we had our Routlets which I think could probably make all of this a lot less complicated, but I didn't want to do a wholesale replacement in this PR, we can save that for a separate PR on its own at some point.
2021-07-07 10:46:41 +00:00
|
|
|
### Routlets
|
2021-03-17 15:58:17 +00:00
|
|
|
|
|
|
|
We use have a concept of 'routlets', the combination of a `<Route />` and
|
|
|
|
`<Outlet />` components that we use within our route templates to achieve
|
|
|
|
several different pieces of functionality.
|
|
|
|
|
|
|
|
Every route template should be wrapped in a `<Route @name={{routeName}}>` component and ever
|
|
|
|
`{{outlet}}` should be wrapped in `<Outlet @name={{routeName}}>` component.
|
|
|
|
The `routeName` variable is made available in every single route template and
|
|
|
|
it equal to the routeName of the current template e.g. `dc.services.index`
|
|
|
|
|
ui: Don't default to the default namespace, use the token default namespace instead (#10503)
The default namespace, and the tokens default namespace (or its origin namespace) is slightly more complicated than other things we deal with in the UI, there's plenty of info/docs on this that I've added in this PR.
Previously:
When a namespace was not specified in the URL, we used to default to the default namespace. When you logged in using a token we automatically forward you the namespace URL that your token originates from, so you are then using the namespace for your token by default. You can of course then edit the URL to remove the namespace portion, or perhaps revisit the UI at the root path with you token already set. In these latter cases we would show you information from the default namespace. So if you had no namespace segment/portion in the URL, we would assume default, perform actions against the default namespace and highlight the default namespace in the namespace selector menu. If you wanted to perform actions in your tokens origin namespace you would have to manually select it from the namespace selector menu.
This PR:
Now, when you have no namespace segment/portion in the URL, we use the token's origin namespace instead (and if you don't have a token, we then use the default namespace like it was previously)
Notes/thoughts:
I originally thought we were showing an incorrectly selected namespace in the namespace selector, but it also matched up with what we were doing with the API, so it was in fact correct. The issue was more that we weren't selecting the origin namespace of the token for the user when a namespace segment was omitted from the URL. Seeing as we automatically forward you to the tokens origin namespace when you log in, and we were correctly showing the namespace we were acting on when you had no namespace segment in the URL (in the previous case default), I'm not entirely sure how much of an issue this actually was.
This characteristic of namespace+token+namespace is a little weird and its easy to miss a subtlety or two so I tried to add some documentation in here for future me/someone else (including some in depth code comment around one of the API endpoints where this is very subtle and very hard to miss). I'm not the greatest at words, so would be great to get some edits there if it doesn't seem clear to folks.
The fact that we used to save your previous datacenter and namespace into local storage for reasons also meant the interaction here was slightly more complicated than it needed to be, so whilst we were here we rejigged things slightly to satisfy said reasons still but not use local storage (we try and grab the info from higher up). A lot of the related code here is from before we had our Routlets which I think could probably make all of this a lot less complicated, but I didn't want to do a wholesale replacement in this PR, we can save that for a separate PR on its own at some point.
2021-07-07 10:46:41 +00:00
|
|
|
### DataSources
|
2021-03-17 15:58:17 +00:00
|
|
|
|
|
|
|
In order to support our live updating long-polling blocking queries we use
|
|
|
|
'DataSources' which come in two flavours. A service backed
|
|
|
|
approach for use within javascript:
|
|
|
|
|
|
|
|
```js
|
|
|
|
class RouteName extends Route {
|
|
|
|
@service('datasource/service') data;
|
|
|
|
async model(params) {
|
|
|
|
return this.data.source(uri => uri`/${params.nspace}/${params.dc}/services`)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
This method returns an Ember proxy that lets you access the data as if it was
|
|
|
|
'just the data', but is also reactive/auto updates when the data in the
|
|
|
|
backend updates, for example:
|
|
|
|
|
|
|
|
```hbs
|
|
|
|
|
|
|
|
{{@model.Name}}
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
And a component based approach for use within templates.
|
|
|
|
|
|
|
|
```hbs
|
|
|
|
<DataSource @src={{
|
|
|
|
uri '/${nspace}/${dc}/services'
|
|
|
|
(hash
|
|
|
|
nspace="default"
|
|
|
|
dc="dc"
|
|
|
|
)
|
|
|
|
}}
|
|
|
|
@onchange=""
|
|
|
|
/>
|
|
|
|
```
|
|
|
|
|
|
|
|
See the relavant component/service documentation for more detail.
|
|
|
|
|
ui: Don't default to the default namespace, use the token default namespace instead (#10503)
The default namespace, and the tokens default namespace (or its origin namespace) is slightly more complicated than other things we deal with in the UI, there's plenty of info/docs on this that I've added in this PR.
Previously:
When a namespace was not specified in the URL, we used to default to the default namespace. When you logged in using a token we automatically forward you the namespace URL that your token originates from, so you are then using the namespace for your token by default. You can of course then edit the URL to remove the namespace portion, or perhaps revisit the UI at the root path with you token already set. In these latter cases we would show you information from the default namespace. So if you had no namespace segment/portion in the URL, we would assume default, perform actions against the default namespace and highlight the default namespace in the namespace selector menu. If you wanted to perform actions in your tokens origin namespace you would have to manually select it from the namespace selector menu.
This PR:
Now, when you have no namespace segment/portion in the URL, we use the token's origin namespace instead (and if you don't have a token, we then use the default namespace like it was previously)
Notes/thoughts:
I originally thought we were showing an incorrectly selected namespace in the namespace selector, but it also matched up with what we were doing with the API, so it was in fact correct. The issue was more that we weren't selecting the origin namespace of the token for the user when a namespace segment was omitted from the URL. Seeing as we automatically forward you to the tokens origin namespace when you log in, and we were correctly showing the namespace we were acting on when you had no namespace segment in the URL (in the previous case default), I'm not entirely sure how much of an issue this actually was.
This characteristic of namespace+token+namespace is a little weird and its easy to miss a subtlety or two so I tried to add some documentation in here for future me/someone else (including some in depth code comment around one of the API endpoints where this is very subtle and very hard to miss). I'm not the greatest at words, so would be great to get some edits there if it doesn't seem clear to folks.
The fact that we used to save your previous datacenter and namespace into local storage for reasons also meant the interaction here was slightly more complicated than it needed to be, so whilst we were here we rejigged things slightly to satisfy said reasons still but not use local storage (we try and grab the info from higher up). A lot of the related code here is from before we had our Routlets which I think could probably make all of this a lot less complicated, but I didn't want to do a wholesale replacement in this PR, we can save that for a separate PR on its own at some point.
2021-07-07 10:46:41 +00:00
|
|
|
### Components
|
2021-03-17 15:58:17 +00:00
|
|
|
|
|
|
|
You could group our components into two different groups:
|
|
|
|
|
|
|
|
1. UI Components - generic components not necessarily specific to the product.
|
|
|
|
2. Consul Components - Components that are specific to Consul/the product.
|
|
|
|
These are mostly 'glorified partials'.
|
|
|
|
|
|
|
|
Mostly the CSS for a component lives in the component folder itself, but if it
|
|
|
|
makes sense for it not to live here, thats fine.
|
|
|
|
|
|
|
|
We currently use a mix of named/block slots and contextual components and its
|
|
|
|
fair to say that we use more named/block slots, but both are fine depending on
|
|
|
|
your use case.
|
|
|
|
|
ui: Don't default to the default namespace, use the token default namespace instead (#10503)
The default namespace, and the tokens default namespace (or its origin namespace) is slightly more complicated than other things we deal with in the UI, there's plenty of info/docs on this that I've added in this PR.
Previously:
When a namespace was not specified in the URL, we used to default to the default namespace. When you logged in using a token we automatically forward you the namespace URL that your token originates from, so you are then using the namespace for your token by default. You can of course then edit the URL to remove the namespace portion, or perhaps revisit the UI at the root path with you token already set. In these latter cases we would show you information from the default namespace. So if you had no namespace segment/portion in the URL, we would assume default, perform actions against the default namespace and highlight the default namespace in the namespace selector menu. If you wanted to perform actions in your tokens origin namespace you would have to manually select it from the namespace selector menu.
This PR:
Now, when you have no namespace segment/portion in the URL, we use the token's origin namespace instead (and if you don't have a token, we then use the default namespace like it was previously)
Notes/thoughts:
I originally thought we were showing an incorrectly selected namespace in the namespace selector, but it also matched up with what we were doing with the API, so it was in fact correct. The issue was more that we weren't selecting the origin namespace of the token for the user when a namespace segment was omitted from the URL. Seeing as we automatically forward you to the tokens origin namespace when you log in, and we were correctly showing the namespace we were acting on when you had no namespace segment in the URL (in the previous case default), I'm not entirely sure how much of an issue this actually was.
This characteristic of namespace+token+namespace is a little weird and its easy to miss a subtlety or two so I tried to add some documentation in here for future me/someone else (including some in depth code comment around one of the API endpoints where this is very subtle and very hard to miss). I'm not the greatest at words, so would be great to get some edits there if it doesn't seem clear to folks.
The fact that we used to save your previous datacenter and namespace into local storage for reasons also meant the interaction here was slightly more complicated than it needed to be, so whilst we were here we rejigged things slightly to satisfy said reasons still but not use local storage (we try and grab the info from higher up). A lot of the related code here is from before we had our Routlets which I think could probably make all of this a lot less complicated, but I didn't want to do a wholesale replacement in this PR, we can save that for a separate PR on its own at some point.
2021-07-07 10:46:41 +00:00
|
|
|
### Significant Addons
|
2021-03-17 15:58:17 +00:00
|
|
|
|
|
|
|
- `ember-data` - model layer
|
|
|
|
- `ember-stargate` - wormhole/portal/put this DOM over there functionality
|
|
|
|
- `ember-can` - user abilities and permissions
|
|
|
|
- `ember-composable-helpers`, `ember-string-fns`, `ember-truth-helpers` - helpers x lots
|
|
|
|
- `ember-changeset` and `ember-changeset-validations` - form validation
|
|
|
|
- `ember-cli-flash` - notifications
|
|
|
|
|
|
|
|
Please see our package.json file dependencies.
|
|
|
|
|
ui: Don't default to the default namespace, use the token default namespace instead (#10503)
The default namespace, and the tokens default namespace (or its origin namespace) is slightly more complicated than other things we deal with in the UI, there's plenty of info/docs on this that I've added in this PR.
Previously:
When a namespace was not specified in the URL, we used to default to the default namespace. When you logged in using a token we automatically forward you the namespace URL that your token originates from, so you are then using the namespace for your token by default. You can of course then edit the URL to remove the namespace portion, or perhaps revisit the UI at the root path with you token already set. In these latter cases we would show you information from the default namespace. So if you had no namespace segment/portion in the URL, we would assume default, perform actions against the default namespace and highlight the default namespace in the namespace selector menu. If you wanted to perform actions in your tokens origin namespace you would have to manually select it from the namespace selector menu.
This PR:
Now, when you have no namespace segment/portion in the URL, we use the token's origin namespace instead (and if you don't have a token, we then use the default namespace like it was previously)
Notes/thoughts:
I originally thought we were showing an incorrectly selected namespace in the namespace selector, but it also matched up with what we were doing with the API, so it was in fact correct. The issue was more that we weren't selecting the origin namespace of the token for the user when a namespace segment was omitted from the URL. Seeing as we automatically forward you to the tokens origin namespace when you log in, and we were correctly showing the namespace we were acting on when you had no namespace segment in the URL (in the previous case default), I'm not entirely sure how much of an issue this actually was.
This characteristic of namespace+token+namespace is a little weird and its easy to miss a subtlety or two so I tried to add some documentation in here for future me/someone else (including some in depth code comment around one of the API endpoints where this is very subtle and very hard to miss). I'm not the greatest at words, so would be great to get some edits there if it doesn't seem clear to folks.
The fact that we used to save your previous datacenter and namespace into local storage for reasons also meant the interaction here was slightly more complicated than it needed to be, so whilst we were here we rejigged things slightly to satisfy said reasons still but not use local storage (we try and grab the info from higher up). A lot of the related code here is from before we had our Routlets which I think could probably make all of this a lot less complicated, but I didn't want to do a wholesale replacement in this PR, we can save that for a separate PR on its own at some point.
2021-07-07 10:46:41 +00:00
|
|
|
## Consul specific
|
|
|
|
|
|
|
|
### Namespace support
|
|
|
|
|
|
|
|
Whilst Consul namespaces are a OSS feature of Consul, we almost always build
|
|
|
|
things 'pretending' that namespaces are always enabled. Then there is code
|
|
|
|
within the data layer of the application that removes any namespace related
|
|
|
|
query parameters.
|
|
|
|
|
|
|
|
Namespaces are a little more complex to think about than other things in
|
|
|
|
Consul as we have the idea of 'the default' namespace, and then additionally
|
|
|
|
an ACL token can have 'a default' namespace (not the same as 'the default'
|
|
|
|
namespace) which is a little like a namespace that is assigned to the token,
|
|
|
|
or where the token originated from. The Consul backend can then use the tokens
|
|
|
|
default/origin/assigned namespace to figure out whether and how to filter any
|
|
|
|
results by namespace before sending those results to the UI.
|
|
|
|
|
|
|
|
When you are requesting data from the API you should always include a
|
|
|
|
namespace (if applicable to the API endpoint), but you should never default
|
|
|
|
the namespace value to 'the default' namespace - `default`. Conversly, when
|
|
|
|
receiving data from an API response, there are some places where we do default
|
|
|
|
a namespace to 'the default' namespace `default`. The easiest way to think
|
|
|
|
about this is: If its on the way out, don't add a default ever, if its on the
|
|
|
|
way in you may need to default any potentially empty Namespace parameters to
|
|
|
|
`default` (due to using Consul without namespaces enabled), there is a
|
|
|
|
NspaceAbility and/or an `env` feature flag to help you to discover this.
|
|
|
|
|
|
|
|
We've made various decisions in the UI to make it hard to omit a namespace
|
|
|
|
when you shouldn't, for example using our DataSource component requires you to
|
|
|
|
include a defined namespace parameter (even if the value for that is `''`),
|
|
|
|
and the route parameter `nspace` value will always default to `''`. It also
|
|
|
|
reminds you to be continually thinking about namespaces whilst adding new
|
|
|
|
features.
|
|
|
|
|
|
|
|
Lastly, we always refer to namespaces in code as the word `nspace` or
|
|
|
|
`nspaces`. Both `ns` and `namespace` have other purposes in Ember and Ember
|
|
|
|
Data (in various places one is significant but not the other and vice versa).
|
|
|
|
Always using the term `nspace` means we avoid any strange bugs or
|
|
|
|
clashes/overwrites with anything in Ember or Ember Data core. The only place
|
|
|
|
where we use `ns` or `Namespace` is to construct API requests/responses.
|
|
|
|
Sometimes when using this term in CSS or on plain javascript objects, this may
|
|
|
|
seem unnecessary but it just helps smooth over writing code around namespaces
|
|
|
|
as you don't have the split second decision of whether you write `ns` or
|
|
|
|
`namespace` - just use `nspace` and everything will be fine :)
|