Some background: I work for a small company who has only just recently decided on the direction of developing RESTful APIs. I work in a very siloed team wherein at the offset of our goal into refactoring our APIs the sum total knowledge of REST API development was virtually 0. This is both positive and negative. It's nice being in a vacuum with no expertise.
There's no hand holding. This means you either hit the books and get busy learning, or you get busy failing. Luckily, I don't really feel intimidated by this challenge. I've been spending a lot of time exploring code written by other teams, completing courses in API development, and reading books on the subject. I've also gained an interest in architecture as of recently. This is all to say that I am neither an expert in (even semi-) modern APIs nor software architecture. But I'm eager to learn and have discussions on the topic.
The discussion: I spend a lot of time thinking about APIs. This is partially due to the fact that some of my colleagues don't get to do that kind of work. Their time is devoted to maintaining legacy ASP.NET web applications. Yikes. This isn't glamorous, but some of the workflows these applications support do provide as thought exercises for the kinds of things one may want to encompass in an API.
One such workflow is the following: we have a page, which when submitted, combines its own inputs along with values from several other forms collected across our platform and does some computation on them. The current implementation performs a Postback in the webpage, then triggers a stored procedure in a SQL server, finally redirecting the user to a page where they can see the status of the work. This design is rife with problems, which is a topic worthy of its own post. Mostly the utter rat's nest of business logic being performed on the database. It is a nightmare.
This has prompted some discussions among myself and other colleagues (who, I assume, are about as experience in web API design as myself). How do we design a RESTful API to act as a gateway to some, potentially long running, procedure while maintaining a resource-oriented appearance? I've spent a bit of time thinking about this, and my solution is what I call the Secretary pattern. Disclaimer, I am not an expert in API design. I am not up to date on current practice. There are, most certainly, better ways to solve this problem (this seems like a situation for which gRPC was designed). However, I see value in playing around with my own solutions to these kinds of problems and learning from them what I can.
We need to remind ourselves the goal is keeping ourselves resource oriented. The temptation is too write URIs like
with weird combinations of HTTP verbiage and oddly formed request bodies. Instead, we think of the API like a "secretary" for work. Our clients will submit "documents" to the secretary which represent work to be done. Now, the backend implementation, the piece that does the work, is abstracted from the consumer. We don't care anymore how the work is done. The API returns a resource representing a "promise" or a "contract" to do some work. The client can continue to make requests for this resource. Which, until completion, will be effectively the same. The secretary will continue to return documents to the client signifying the receipt of a request of work. Once complete, our response will change. Instead, giving the client a document representing the completed promise to do work, with some link to the resource which actually contains the data the user initially described.
So what's this all about
I'm currently teaching myself architecture and distributed application design by reading some good books:
and also absorbing what can be had at work.
I'm also trying to learn RUST. I've been reading a lot of The Rust Book and I've also tried my hand at some Rust by submitting pull requests on some repositories on GitHub. Right now, I'm trying to write a simple task list application in Rust (I am notoriously bad at giving myself pet projects to learn the ropes of new languages). What's up next is to create an implementation of the Secretary pattern in Rust. -->