2
\$\begingroup\$

I have a REST API using the Laravel framework and the front-end uses the Vue.js framework. It is a dashboard for an e-commerce store where you can connect to a post shipment service API to upload order shipment data and get a tracking number (with a label in PNG format). So after it receives a tracking number label from post service API it needs to show it in the front-end from the REST API response.

I have a route on the front-end shipments/:id/tracking/label which should show some shipment data and tracking label image.

I have 2 solutions for this. Which is better and why?

Send image content as base-64 encoded string and shipment data in one backend route GET shipments/{id}/tracking/label

Backend:

 public function getTrackingLabel(Shipment $shipment, LabelIsraelPostService $service) { $data = [ 'label' => $service->getTrackingLabel($shipment->label_path), 'shipment' => $shipment ]; return response()->json(['shipment' => $data]); } 

Frontend:

 <v-card> <v-card-title> Order id : {{ shipment.order_id }} </v-card-title> <v-img max-width="700" :src="`data:image/png;base64,${shipment.link}`" > </v-img> </v-card> 

Use 2 different backend routes GET shipments/{id} for all shipment data and another one for only image GET shipments/{id}/tracking_label which will return image with headers.

Backend:

For getting all shipment data:

 public function show(Shipment $shipment) { return response()->json(['shipment' => $shipment]) } 

For getting shipment tracking label image:

 public function getTrackingLabel(Shipment $shipment, LabelIsraelPostService $service) { return response(Storage::cloud()->get($path))->header('content-type', 'image\png') } 

Front-end usage:

 <v-card> <v-card-title> Order id : {{ shipment.order_id }} </v-card-title> <v-img max-width="700" :src="`${BASE_API_URL}/shipments/${shipment.id}/tracking/label`"//or use axios for this request > </v-img> </v-card> 

This will upload the image in a browser from the API route and send another request to get all shipment data and show it on the front end.

I like solution #2 but if I will have 10 shipments for showing tracking number label, I will have 10 API calls for getting an image for each of them, and also one for getting an array of shipments data by ids. In solution #1 I can use only one API call for all shipments with data and base64 image for each of them.

What is best practice to send image as the REST API response and show it with JS front end?

\$\endgroup\$
4
  • \$\begingroup\$ Usually images are their own request anyway, so for me personally, I would just use the images as a separate request. I would however include the url to the image in the data request, rather then trying to construct the url in js, eg, ${shipment.url_label} \$\endgroup\$ Commented Dec 15, 2019 at 17:00
  • \$\begingroup\$ @bumperbox thx for you comment, what if i want to do image as private, so for request it i need auth? Currently route for request image is public \$\endgroup\$ Commented Dec 16, 2019 at 13:56
  • \$\begingroup\$ you can add security by returning the image as a response from a laravel controller action, stackoverflow.com/questions/36066144/… \$\endgroup\$ Commented Dec 18, 2019 at 16:19
  • \$\begingroup\$ @bumperbox how then i need to show it on vue front, for me i see only one solution - base64 decode from backend response \$\endgroup\$ Commented Dec 19, 2019 at 17:04

1 Answer 1

3
\$\begingroup\$

Addressing the question

I have 2 solutions for this. Which is better and why?

The answer may depend on mulitple factors. For example - if there were parts of the front-end which only needed the shipment data without the image then it may make sense. However if there is only really one place where both the shipment data and image are needed then for the sake of fewer connections having one endpoint may be optimal.

I like solution #2 but if I will have 10 shipments for showing tracking number label, I will have 10 API calls for getting an image for each of them, and also one for getting an array of shipments data by ids. In solution #1 I can use only one API call for all shipments with data and base64 image for each of them.

Perhaps you are familiar with Resource Collections and unless there is some aspect which would prevent their usage in this application it might be useful for minimizing API requests.

Code Review

There isn't a ton of code to critique here. The code looks quite good though I did have a couple points to mention.

Consider adding return type declarations

It isn't required but since the method parameters have types declared it would be fitting to add return type declarations.

Consider eliminating single use variables.

There is one variable used only once after it is declared - in the first example of the backend method getTrackingLabel():

 $data = [ 'label' => $service->getTrackingLabel($shipment->label_path), 'shipment' => $shipment ]; return response()->json(['shipment' => $data]); 

That could be simplified by moving the array into the spot it is used in the return statement:

 return response()->json([ 'shipment' => [ 'label' => $service->getTrackingLabel($shipment->label_path), 'shipment' => $shipment ] ]); 

Obviously some may have a difference in opinion about spacing and whether it is worth structuring it this way.

\$\endgroup\$

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.