4 ms·
You're not wrong, and to resolve this, I've implemented something of an in-between for APIs I work on, which I call a "Multi-Endpoint Query". It's a restful(-i
by enobrev 6y ago
You're not wrong, and to resolve this, I've implemented something of an in-between for APIs I work on, which I call a "Multi-Endpoint Query". It's a restful(-ish) API, but there's an additional endpoint called "query", which allows for an array of endpoints to gather information from sequentially. The most useful bit of this is that information gathered from earlier in the array can be used as referenced later in the array.
For instance:
"query": [
"/api/category/books/products",
"/api/products/{products.id}/images",
"/api/products/{products.id}/reviews",
"/api/users/{reviews.user_id}"
]
When the endpoint gets this query, it will run a GET on the first endpoint. And then it uses the results from that first endpoint to fill in the uri template on the 2nd endpoint, which would become something like "/api/products/2,4,17/images". And the results of all previous endpoints are merged into the response and can be used to fill subsequent uri templates as well.
As far as the client is concerned this is all done in a single API request. The first version was making literal HTTP requests to localhost, but now is built to call the endpoints directly (internally, no HTTP). This system requires some convention in the responses to make it work, but that convention ends up making responses predictable and easily reusable. Overall it's worked very well and requires almost no additional effort.
I have a similar endpoint that also allows "POST"s which makes for seriously complex single-request interactions, but I don't use that as much due to the inherent complexity of it - at least not for client-side APIs.
When I first looked into GQL, it looked pretty fancy, but seemed to require quite a bit more maintenance to define the query space. This was before a lot of today's libraries were available. So I hacked together the Multi-Endpoint Query, assuming if it failed, I could go back to GQL when there were more libraries available. But I haven't really needed to do so since.
- coding123 6y agoAnd there's nothing wrong with that. You essentially invented your own GQL because it contained some awesome ideas. Also I think it would be OK if new things similar to GQL came out and challenged it. I don't think GQL is perfect, and I personally wish it had namespacing and more thought about caching built in.
- mssundaram 6y agoGiven your example request, what would be the schema of the response?
- enobrev 6y agoThat query is completely contrived (doesn't match anything I'm working on), but here's what the response would look like: { "products": { "abc123": { "id": "abc123", "name": "Some Widget" }, "def456": { "id": "def456", "name" "Some Other Widget" } }, "images": { "xyzabc": { "id": "xyzabc", "product_id": "abc123" "url": "https://example.com/xyzabc" } }, "reviews": { "4": { "id": "4", "product_id": "abc123", "user_id": "hjk453" "review": "This thing sucks!" } "15": { "id": "15", "product_id": "abc123" "user_id": "pos999" "review": "I love this thing!" } }, "users": { "hjk453": { "id": "hjk453", "handle": "somebody", "name": "Some Body" }, "pos999": { "id": "pos999", "handle": "someone", "name": "Some One" } } }
- tsss 6y agoThis is an API gateway or backend-for-frontend.
- enobrev 6y agoBackend. It's essentially an API gateway, although on my API it's just another endpoint. Behind the scenes it calls the other endpoints.