How to trigger argo workflow from an API request? - argo-workflows

What is the best way to trigger an argo workflow from an API request?
The API request is handled by a web server, how does the server submits the workflow to the argo server? Using the CLI? using a rest request? What is the best/recommended approach here?

There's no one "right way." But here are some of the options, so you can pick the one that makes the most sense for your application:
Use the Argo API
with an SDK (Java, Go, Python)
If your API is written in Java, Go, or Python, and if your interactions with Argo are more complex than simply submitting a Workflow (for example, if you're also listing Workflows and would like a nice representation of those objects), an Argo Workflows SDK might be a good choice. In my experience the SDKs have quirks and bugs, so I'd only dive in if you need a more full-featured client.
directly with some HTTP client
If your use case is very simple (like submitting a small Workflow with a WorkflowTemplate reference), I would recommend using a direct HTTP call to the Argo or Kubernetes API.
Use a webhook
The webhook endpoint is technically part of the API, but it's a bit different. The API is basically a specialized version of the Kubernetes API, tailored to the Argo CRDs. The events API endpoint provides some additional features specific to kicking off workflows.
Use the CLI
You'd have to fork the CLI process from your server code, so this probably isn't the "cleanest" approach.
Use Argo Events
Argo Events is a separate but closely-related project. It can accept a variety of inputs (webhooks, pub/sub messages, etc) and then trigger a Workflow.
Argo Events could make sense if, for example, you want an external record of all the workflows submitted. Pub/sub would give you that record.
Use the Kubernetes API or CLI
Workflows are just Kubernetes resources, so you can just submit them via Kubernetes mechanisms if you like. If your language has a robust Kubernetes SDK, that's a solid choice.
As I'm sure you can tell, it really depends on the application. Let me know if any of these needs clarification.

Related

Swagger multiple definitions best practices

I have an API, and a consumer web app, both written in Node and Express. The API is defined by a OpenAPI Specification. Implemented by swagger-ui-express.
The above web apps are Dockerised and managed in Kubernetes.
The API has a handful of endpoints for managing the lifecycle of a user's registration/application to the service.
Currently, when I need to cleardown completed/abandoned applications, or resubmit failed applications, I employ a periodically run cronjob to carry out a database query for the actions mentioned. The cronjob is defined by a Kubernetes config YAML file. This is quickly becoming unmanageable, and hard to maintain.
I am looking in to having a dedicated endpoint for each of the above tasks. Then a dedicated cronjob could periodically send a request to the API endpoint to carry out the complex task. This moves the business logic back in to the API, and avoids duplication within a cronjob hosted elsewhere. I am ultimately asking if this is a good approach or is there a better workflow documented somewhere I could implement?
My thinking is that I could add these new endpoints to the already-existing consumer API, but have the new (housekeeping/management) endpoints separated from the others.
To separate each (current) endpoint in to their respective resource, I am defining tags within the specification. Tags don't seem to be sufficient for the separation of these new "housekeeping" endpoints.
Looking through the SwaggerUI documentation I can see that I can define multiple definitions (via the urls property) to switch between. These definitions being powered by individual Specification documents. This looks like a very clean way of separating the consumer API from the admin API, is this best practice?
Any input would be appreciated on this as I am struggling to find much documentation on this kind of issue.

How to record api calls to mock in SwaggerHub?

I want to mock api calls from my application, and host the mock, so my tests can work without calls to real api. There is a service called restbird which does exactly that, but it is far from ideal for me. If you want to collaborate you have to host the service by your self. Also it has some errors like not displaying history of calls, or when it sends server errors for no reason. I want a service more robust than this one.
The only service that I think might be a good fit is SwaggerHub, it seems robust, it has virtual servers, and overall it is very popular. But the only problem is that I cannot find a way to record api calls from my application. So how can I record api calls for SwaggerHub?
There does not currently exist any functionality within SwaggerHub itself to record API calls made from the Swagger UI module within the tool. This is a limitation of the open-source Swagger UI tool.
What I can recommend is you use the Swagger Inspector tool. The Swagger Inspector can be used to make API calls from a client, save both the request and the response, and even generate an OpenAPI file for you based off the request/responses. If you create an account and sign in, you can even save your API calls to a collection to use later.
Swagger Inspector: https://inspector.swagger.io/builder
It may also be worth considering using ReadyAPI's Virtualization module to handle this use case. With ReadyAPI Virtualization you can record transactions from a browser, build mock services from the recorded transaction or an existing API definition, and then host the mock service using VirtServer.
ReadyAPI is a part of SmartBears API lifecycle products, so there are integrations between the two tools. For instance, you can port APIs from Swaggerhub into ReadyAPI directly and you can use mock services built in ReadyAPI to do dynamic mocking in Swaggerhub.
You can find more information about ReadyAPI Virtualization here: https://smartbear.com/product/ready-api/api-virtualization/
I realise this is a very late response to this thread, but hopefully this information comes in handy.

What are some methods to document contracts between microservices?

In an HTTP-driven microservices architecture, each service might have a number of public endpoints that return JSON, for example, to a client or an API gateway intermediary. These services could also accept POSTs with JSON bodies of a certain shape, or query strings of a certain shape, etc.
What are some good options for documenting or programmatically keeping track of these "contracts" between services? I.e, if service A's /getThing endpoint has been refactored to return different data, is there a documentation tool or methodology that would facilitate updating the API gateway to adapt to this change?
For programmatically management of contracts, if you using spring-cloud stack then you must look into spring-cloud-contract, by which you can easily keep track of your latest version of contracts for your Rest endpoints and also if any change occurs in your api endpoint, this will help you notify by breaking the contract and failing the test-cases build around it.
Let's say for example, service A's /getThing endpoint has been refactored to return different data then all calling services to this endpoint will fail while build time of your project.
However, this methodology won't facilitate updating the API gateway to adapt to this change as there might different logic you want to perform of every new version of your endpoints.
You can also create Rest Docs snippets using these endpoint contracts. checkout Rest Docs snippets. You can also use swagger for documenting your endpoints.
for NodeJs check here.

Public valid REST Api with wolkenkit.io

I am currently evaluating the framework "wolkenkit" [1] for using it in an application. Within this application I will have a user interface for tenant-based data management. Only authenticated users will have access to this application.
Additionally there should be a public REST API following common standards and being callable by public (tenant security done with submission of a tenant-based API Key within the request headers).
As far as I have found out, the wolkenkit REST API does not seem to fit these standards in forms of HTTP verbs.
But as wolkenkit at all appears to me as a really flexible and easy-to-use framework, I wonder how to basically implement such a public API.
May it be e.g. a valid approach to create an own web application which internally connects to the wolkenkit backend? What about the additional performance overhead then?
[1] https://www.wolkenkit.io/
In addition to the answer of mattwagl, I would like to point out a few things that you may be interested in.
First of all, since wolkenkit is based on CQRS, the application has a separate API for writing and reading. That means, that if you send a command (whose intent is to change state) this goes to the write API. If you subscribe for events or run a query, this goes to the read API.
This again means, that if you send a command, it's up to the write side to respond to it. As the write side is not meant to return application state, all it says is basically: "Thanks, I have received the command." To get the actual result you have to wait for the appropriate event, which means subscribing to the read API.
In the wolkenkit documentation there is a nice diagram which shows this in a clear way:
If you now add a separate REST API (which actually fulfills the requirements of REST), this means that you need to handle waiting for the result internally. In other words: Clients in wolkenkit are always meant to be asynchronous, REST is not. Hence it's your job to handle the asynchronous behavior of the wolkenkit APIs in your REST API. I think that this is the hardest part.
Once you have done this, you will have a synchronous REST API, and of course it will have some overhead. But I think that since its overhead is limited to passing through and translating network requests, it should be negligible.
Oh, and finally, there is another thing that you have to watch out for: Since REST as it was meant originally relies on the HTTP verbs to transport semantics, you need to map GET / POST / PUT / DELETE to the semantic commands of wolkenkit. As long as this can be done 1:1, everything's fine – problems start when there are multiple commands that (technically speaking) do an UPDATE.
PS: I'm also one of the developers of wolkenkit.
PPS: However you are going to solve this, I would be highly interested to hear from you! It would be very great if you could share your experiences with us, as you are most probably not the last one with this idea. If you want to contact us, the easiest way would be via Slack.
wolkenkit applications can be accessed using an HTTP- and a Websocket-API. These APIs are both provided by the tailwind module that wolkenkit uses under the hood. In the tailwind repo you can find a very simple documentation of the available HTTP routes.
You're right, the wolkenkit HTTP-API is not a classic REST-API. It's more RPC-style which in our experience is a good fit for applications. There are only 3 routes that your clients/tenants need to support: /v1/command (POST) is used for issuing commands. The commands you post should follow the command schema. /v1/events (POST) can be used for streaming events to clients. These events will follow the event schema. Finally you have /v1/read/:modelType/:modelName (POST) to read models. You can simply use HTTPie to test these routes.
Authentication of these APIs is currently done using OpenID-Connect. There's a very detailed article on how to setup authentication using Auth0. I'm not quite sure if this fits your use-case but you could basically use any Authentication Service that follows this standard or that is able to issue JWT tokens.
Finally you could also build your own JavaScript client-SDK that runs inside browsers by building a module that uses the wolkenkit-client-js under the hood. This SDK can just use the same API as any other client to connect to your application.
Hope this helps.
PS: Please note that I am one of the authors of wolkenkit.

Are there any online REST API sandbox/playground

I am looking for a quick way to spin up a very simple REST api, for testing purposes.
Specifically I want to be able to handle CORS preflight requests (i.e need ability to handle the OPTIONS verb)
E.g: A service that spins up a temporary node instance with express and allows me to add request handlers and gives me a temporary url. Or the equivalent in another language (java, ruby, etc)
Maybe try https://code.runnable.com it allows you to quickly build and run whole express apps and it allows multiple different languages not just node.js.