-
Notifications
You must be signed in to change notification settings - Fork 1
Updated dependencies doc to be a little more use-case focused #23
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
454e99e
8afb234
44da6d6
cfc5bc3
dd2e73d
c5e1f28
ac73f94
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -1,59 +1,93 @@ | ||||||
| --- | ||||||
| title: "Dependencies" | ||||||
| description: | ||||||
| "Architect was designed with the future in mind, and the future of any team | ||||||
| building distributed software is a complex web of services." | ||||||
| title: Dependencies | ||||||
| --- | ||||||
|
|
||||||
| Historically this complex web of services has been hard to manage, hard to | ||||||
| reason about, and hard for developers to contribute to. | ||||||
| Historically cloud teams have tried to avoid dependencies and coupling between microservices and APIs | ||||||
| because it creates a lot of infrastructure and CI/CD complexity. However, its all too natural for | ||||||
| developers to try to extend what exists rather than reinvent it, and many teams ended up with complex | ||||||
| webs of microservices nonetheless. | ||||||
|
|
||||||
| Fortunately, the graphing and collaboration problems this creates have been | ||||||
| solved before. We've seen it with object-oriented programming and inheritance, | ||||||
| and even more recently with package and dependency management. All of our | ||||||
| favorite languages have a way for developers to utilize dependencies through a | ||||||
| resolver to handle the artifact storage, complex graphing, and de-duplication | ||||||
| needed to manage them at-scale. Architect takes this same approach to make it | ||||||
| easier than ever for developers to extend cloud services. | ||||||
| Fortunately, this problem of "dependencies" has been solved before. Every language and operating system | ||||||
| on earth has tools for dependency management to help developers collaborate and extend each others work. | ||||||
| Now Architect is here to provide the same value for APIs and microservices. | ||||||
|
|
||||||
| ## Utilizing dependencies | ||||||
| ## Why use dependencies? | ||||||
|
|
||||||
| ```yaml | ||||||
| Citing dependencies as part of your component is not the most natural way for developers to integrate with | ||||||
| software made by other teams, but its also the only way to achieve [on-demand environments](/deployments/automated-previews) | ||||||
| for distributed applications. | ||||||
|
|
||||||
| Every time a component is deployed with Architect, it will automatically deploy (if needed) and connect to | ||||||
| cited dependencies. Perhaps even more impressive than that is that it will also deploy the dependencies OF your | ||||||
| component's dependencies and ensure they're integrated as well. | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
|
||||||
| Without dependency management integrated into deployments, each and every application would have to maintain a | ||||||
| complex web of CI pipelines or centralized infrastructure-as-code (IaC) templates to create new environments which | ||||||
| can be an educational and logistical nightmare. With Architect, all you ever need to know is your immediate dependencies | ||||||
| and the rest will be automated for you. | ||||||
|
|
||||||
| ## Registering dependencies | ||||||
|
|
||||||
| Before we can begin using dependencies, we need to register a component that will act as a dependency for others. There | ||||||
| are no restrictions on what type of component can be used as a dependency. All you need is to run the `register` command | ||||||
| to publish your component to Architect's cloud registry. | ||||||
|
|
||||||
| <Note> | ||||||
| If you're component builds docker images from source, those images will also be published to Architect's registry with | ||||||
| the same access rights. | ||||||
| </Note> | ||||||
|
|
||||||
| ```sh | ||||||
| $ architect register ./backend --tag latest --account my-account | ||||||
| ``` | ||||||
|
|
||||||
| Haven't created a component before? Check out the [creating components](/guides/create-a-component) guide to learn more. | ||||||
|
|
||||||
| ## Using dependencies | ||||||
|
|
||||||
| Now that we have a component in the registry, we can use it as a dependency for another one. Citing another component as | ||||||
| a dependency is easy using the `dependencies` block inside the component spec. The below example shows how to cite a component | ||||||
| named `backend` as a dependency so that it gets automatically deployed with your own component. | ||||||
|
|
||||||
| ```yaml architect.yml | ||||||
| dependencies: | ||||||
| authentication: latest | ||||||
| backend: latest | ||||||
| ``` | ||||||
|
|
||||||
| You may also want to integrate with one or more services inside the dependency component. You can easily point to `services`, `outputs`, | ||||||
| and other resources declared inside dependencies using Architect's expression syntax: | ||||||
|
|
||||||
| ```yaml architect.yml | ||||||
| services: | ||||||
| my-api: | ||||||
| interfaces: | ||||||
| http: 8080 | ||||||
| app: | ||||||
| build: | ||||||
| context: ./ | ||||||
| environment: | ||||||
| AUTH_INTERNAL: ${{ dependencies['authentication'].services.auth.interfaces.main.url }} | ||||||
| AUTH_EXTERNAL: ${{ | ||||||
| dependencies['authentication'].services.auth.interfaces.main.ingress.url | ||||||
| }} | ||||||
| BACKEND_ADDR: ${{ dependencies.backend.services.api.interfaces.main.url }} | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would explain where this address comes from and possibly link to components/service-discovery
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see you bring in service discovery below. It would still be helpful to explain here that the address comes from the backend app's service declaration in its own architect.yml file. |
||||||
| ``` | ||||||
|
|
||||||
| Just like with your favorite package manager, developers can cite the names and | ||||||
| versions of the components that they need to make calls to. Not only will this | ||||||
| allow Architect to provision the dependency automatically, it will also allow | ||||||
| developers to pin to specific versions and ensure that the APIs don't change out | ||||||
| from under them. | ||||||
|
|
||||||
| ## Dependency referencing syntax | ||||||
|
|
||||||
| We've already shown how Architect enables developers to take advantage of | ||||||
| [service discovery](/components/service-discovery) for connecting to peer | ||||||
| services, and the same approach can be used to connect to the interfaces of | ||||||
| component dependencies. Once you've specified a dependency in your component, | ||||||
| you can reference the interfaces of said dependency using the | ||||||
| `${{ dependencies.*.services.*.interfaces.* }}` expression context. | ||||||
|
|
||||||
| | field | description | | ||||||
| | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | ||||||
| | url | The fully composed URL of the reference interface. This will take the format, `<protocol>://<username>:<password>@<host>:<port><path>`. | | ||||||
| | protocol | The protocol of the interface being referenced. This will always be the specific value assigned to the interface by the developer. | | ||||||
| | username | The username of the interface being referenced. Not all interfaces have usernames, so this will be an empty string if none is set. | | ||||||
| | password | The password of the interface being referenced. Not all interfaces have passwords, so this will be an empty string if none is set. | | ||||||
| | host | The host value of the interface being referenced. This value is usually dynamic to accomodate the differences between service discovery solutions available to each environment. | | ||||||
| | port | The port value of the interface being referenced. | | ||||||
| | path | The path value of the interface being referenced. Not all interfaces have paths, so this will be an empty string if none is set. | | ||||||
| ### Available references | ||||||
|
|
||||||
| Service addresses aren't the only thing you can inject into your own component from dependencies. Developers can | ||||||
| point to just about any resoure declared by the dependency to enrich their own configuration: | ||||||
|
|
||||||
| | Key | Description | | ||||||
| | ------------------------------- | -------------------------------------------------- | | ||||||
| | `dependencies.<name>.services` | Allows you to inject values associated with [services](/components/services) inside the dependency | | ||||||
| | `dependencies.<name>.databases` | Allows you to inject values associated with [databases](/components/databases) inside the dependency | | ||||||
| | `dependencies.<name>.outputs` | Allows you to inject output values issued by the dependency | | ||||||
|
|
||||||
| ## Debugging dependencies | ||||||
|
|
||||||
| By default Architect will pull dependencies down from the cloud registry on every deployment. But if you want to test changes to | ||||||
| two components at once, you can do so by linking the dependency to your host machine with `architect link`. This will cause Architect | ||||||
| to use the local version of the components rather than trying to pull them from the Architect cloud registry. This is helpful when | ||||||
| you are actively developing multiple components that are dependent on one another. | ||||||
|
|
||||||
| ```sh | ||||||
| # Tells architect to use the local source code to fulfill dependencies on the `backend` | ||||||
| $ architect link ./backend/ | ||||||
|
|
||||||
| # Will build and connect to the backend code found locally instead of the docker images pulled from Architect Cloud | ||||||
| $ architect dev ./frontend/ | ||||||
| ``` | ||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure this suggestion captures what I was trying to say which is that we deploy the dependencies you didn't know you had as well (e.g. the dependencies OF your own dependencies). Is there a better way to phrase that that you can think of?