From 454e99e00bedb4cd0f0c455bf714860e6b3c57c6 Mon Sep 17 00:00:00 2001 From: David Thor Date: Sun, 26 Mar 2023 11:25:33 -0400 Subject: [PATCH 1/7] Updated dependencies doc to be a little more use-case focused --- components/dependencies.mdx | 140 ++++++++++++++++++++++++------------ 1 file changed, 93 insertions(+), 47 deletions(-) diff --git a/components/dependencies.mdx b/components/dependencies.mdx index a8a3a4a..898c83b 100644 --- a/components/dependencies.mdx +++ b/components/dependencies.mdx @@ -1,59 +1,105 @@ --- -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 +description: Integrate with other APIs using common dependency management tactics --- -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](/environments/pull-request) +for [distributed applications](/architecture/microservices). + +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 create a component that we want to act as a dependency for another. +Let's start by creating a new component that we'll call the `backend` of our project. The command below will help you +create a new component from one of Architect's starter projects. + +```sh +$ architect init backend +``` + +Now that we have the project created, let's go ahead and register it with Architect. This will simply build the services +into docker images and publish everything to Architect's cloud registry. + +```sh +$ architect register ./backend --tag latest --account my-account +``` + +## Using dependencies + +Now that we have a component in the registry, we can use it as a dependency for another one. Let's create a second project +and call it `frontend`. + +```sh +$ architect init frontend +``` + +Next, let's open up `./frontend/architect.yml` in our favorite IDE so we can add the dependency. First, let's cite the dependency +so that the backend will be deployed alongside the frontend. Add the following to the component configuration: + +```yaml architect.yml dependencies: - authentication: latest + backend: {} +``` +Next, we'll need to ensure the frontend service has access to the backend API. Find the `environment` variables of the `app` service +and add the following: + +```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. | + + SPAs and static websites run in the browser and need to connect to the external **ingress** URLs. Click here to learn more. + + +Finally, let's deploy our application! We haven't written any code to connect to the backend API, but you'll see that the +backend got automatically deployed, and you're welcome to go try writing features that leverage it. + +## Available pointers + +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`: + +```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 From 8afb23464a2db474b79b892216061471b615f335 Mon Sep 17 00:00:00 2001 From: David Thor Date: Sun, 26 Mar 2023 11:27:50 -0400 Subject: [PATCH 2/7] Forgot we hadn't updated the dependencies syntax yet --- components/dependencies.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/dependencies.mdx b/components/dependencies.mdx index 898c83b..408ca11 100644 --- a/components/dependencies.mdx +++ b/components/dependencies.mdx @@ -58,7 +58,7 @@ so that the backend will be deployed alongside the frontend. Add the following t ```yaml architect.yml dependencies: - backend: {} + backend: latest ``` Next, we'll need to ensure the frontend service has access to the backend API. Find the `environment` variables of the `app` service From 44da6d62925d02c5532152a2aeb1fc224fcb3014 Mon Sep 17 00:00:00 2001 From: David Thor Date: Mon, 27 Mar 2023 07:10:55 -0400 Subject: [PATCH 3/7] Removed bad comma Co-authored-by: Mandy Hubbard --- components/dependencies.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/dependencies.mdx b/components/dependencies.mdx index 408ca11..0bddda9 100644 --- a/components/dependencies.mdx +++ b/components/dependencies.mdx @@ -93,7 +93,7 @@ point to just about any resoure declared by the dependency to enrich their own c ## Debugging dependencies -By default Architect will pull dependencies down from the cloud registry on every deployment. But if you want to test changes to, +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`: ```sh From cfc5bc3c861bb82a69b20cdc047c2d4f1af9fdf6 Mon Sep 17 00:00:00 2001 From: David Thor Date: Mon, 27 Mar 2023 07:11:09 -0400 Subject: [PATCH 4/7] Removed description Co-authored-by: Mandy Hubbard --- components/dependencies.mdx | 1 - 1 file changed, 1 deletion(-) diff --git a/components/dependencies.mdx b/components/dependencies.mdx index 0bddda9..0193bab 100644 --- a/components/dependencies.mdx +++ b/components/dependencies.mdx @@ -1,6 +1,5 @@ --- title: Dependencies -description: Integrate with other APIs using common dependency management tactics --- Historically cloud teams have tried to avoid dependencies and coupling between microservices and APIs From dd2e73db14869f35d07c92683a534e9e129374b2 Mon Sep 17 00:00:00 2001 From: David Thor Date: Mon, 27 Mar 2023 07:18:03 -0400 Subject: [PATCH 5/7] Docker is a proper noun Co-authored-by: Mandy Hubbard --- components/dependencies.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/dependencies.mdx b/components/dependencies.mdx index 0193bab..20aa973 100644 --- a/components/dependencies.mdx +++ b/components/dependencies.mdx @@ -37,7 +37,7 @@ $ architect init backend ``` Now that we have the project created, let's go ahead and register it with Architect. This will simply build the services -into docker images and publish everything to Architect's cloud registry. +into Docker images and publish everything to Architect's cloud registry. ```sh $ architect register ./backend --tag latest --account my-account From c5e1f284f4fbbf2257366ade5dd94d43e36f1682 Mon Sep 17 00:00:00 2001 From: David Thor Date: Mon, 27 Mar 2023 07:19:03 -0400 Subject: [PATCH 6/7] Added better description to architect link command Co-authored-by: Mandy Hubbard --- components/dependencies.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/dependencies.mdx b/components/dependencies.mdx index 20aa973..5ee6a40 100644 --- a/components/dependencies.mdx +++ b/components/dependencies.mdx @@ -93,7 +93,7 @@ point to just about any resoure declared by the dependency to enrich their own c ## 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`: +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` From ac73f94592d9f0d768e8c791ed3e84ee5955a639 Mon Sep 17 00:00:00 2001 From: David Thor Date: Mon, 27 Mar 2023 09:00:45 -0400 Subject: [PATCH 7/7] Updated based on feedback on PR --- components/dependencies.mdx | 51 +++++++++++++++---------------------- 1 file changed, 20 insertions(+), 31 deletions(-) diff --git a/components/dependencies.mdx b/components/dependencies.mdx index 5ee6a40..fb34be5 100644 --- a/components/dependencies.mdx +++ b/components/dependencies.mdx @@ -14,8 +14,8 @@ Now Architect is here to provide the same value for APIs and microservices. ## Why use dependencies? 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](/environments/pull-request) -for [distributed applications](/architecture/microservices). +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 @@ -28,40 +28,34 @@ and the rest will be automated for you. ## Registering dependencies -Before we can begin using dependencies, we need to create a component that we want to act as a dependency for another. -Let's start by creating a new component that we'll call the `backend` of our project. The command below will help you -create a new component from one of Architect's starter projects. +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. -```sh -$ architect init backend -``` - -Now that we have the project created, let's go ahead and register it with Architect. This will simply build the services -into Docker images and publish everything 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 ``` -## Using dependencies - -Now that we have a component in the registry, we can use it as a dependency for another one. Let's create a second project -and call it `frontend`. +Haven't created a component before? Check out the [creating components](/guides/create-a-component) guide to learn more. -```sh -$ architect init frontend -``` +## Using dependencies -Next, let's open up `./frontend/architect.yml` in our favorite IDE so we can add the dependency. First, let's cite the dependency -so that the backend will be deployed alongside the frontend. Add the following to the component configuration: +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: backend: latest ``` -Next, we'll need to ensure the frontend service has access to the backend API. Find the `environment` variables of the `app` service -and add the following: +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: @@ -72,14 +66,7 @@ services: BACKEND_ADDR: ${{ dependencies.backend.services.api.interfaces.main.url }} ``` - - SPAs and static websites run in the browser and need to connect to the external **ingress** URLs. Click here to learn more. - - -Finally, let's deploy our application! We haven't written any code to connect to the backend API, but you'll see that the -backend got automatically deployed, and you're welcome to go try writing features that leverage it. - -## Available pointers +### 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: @@ -93,7 +80,9 @@ point to just about any resoure declared by the dependency to enrich their own c ## 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. +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`