diff --git a/components/dependencies.mdx b/components/dependencies.mdx index a8a3a4a..fb34be5 100644 --- a/components/dependencies.mdx +++ b/components/dependencies.mdx @@ -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. + +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. + + + If you're component builds docker images from source, those images will also be published to Architect's registry with + the same access rights. + + +```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 }} ``` -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 | 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..services` | Allows you to inject values associated with [services](/components/services) inside the dependency | +| `dependencies..databases` | Allows you to inject values associated with [databases](/components/databases) inside the dependency | +| `dependencies..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/ +``` \ No newline at end of file