JavaRush /جاوا بلاگ /Random-UR /REST API اور ڈیٹا کی توثیق
Денис
سطح
Киев

REST API اور ڈیٹا کی توثیق

گروپ میں شائع ہوا۔
پہلے حصے کا لنک: REST API اور اگلا ٹیسٹ ٹاسک ٹھیک ہے، ہماری ایپلی کیشن کام کر رہی ہے، ہمیں اس سے کسی قسم کا رسپانس مل سکتا ہے، لیکن یہ ہمیں کیا دیتا ہے؟ یہ کوئی مفید کام نہیں کرتا۔ جلد ہی کہا گیا ہے، آئیے کسی مفید چیز کو نافذ کریں۔ سب سے پہلے، آئیے اپنے build.gradle میں کچھ نئے انحصار شامل کریں، وہ ہمارے لیے مفید ہوں گے:
implementation 'org.apache.commons:commons-lang3:3.12.0'
implementation 'org.apache.commons:commons-collections4:4.4'
implementation 'org.springframework.boot:spring-boot-starter-validation'
اور ہم اصل ڈیٹا کے ساتھ شروع کریں گے جس پر ہمیں عمل کرنا چاہیے۔ آئیے اپنے استقامت کے پیکیج پر واپس آتے ہیں اور ہستی کو بھرنا شروع کرتے ہیں۔ جیسا کہ آپ کو یاد ہے، ہم نے اسے صرف ایک فیلڈ کے ساتھ موجود رہنے کے لیے چھوڑ دیا ہے، اور پھر آٹو کو `@GeneratedValue(strategy = GenerationType.IDENTITY)` کے ذریعے تیار کیا جاتا ہے، آئیے پہلے باب سے تکنیکی وضاحتیں یاد رکھیں:
{
  "firstName": String,
  "lastName": String,
  "department": String,
  "salary": String
  "hired": String //"yyyy-mm-dd"
  "tasks": [
  ]
}
ہمارے پاس پہلی بار کافی فیلڈز ہیں، تو آئیے اسے لاگو کرنا شروع کریں۔ پہلے تین فیلڈز سوال نہیں اٹھاتے ہیں - یہ عام لائنیں ہیں، لیکن تنخواہ کا میدان پہلے سے ہی تجویز کردہ ہے۔ اصل لائن کیوں؟ حقیقی کام میں ایسا بھی ہوتا ہے، ایک گاہک آپ کے پاس آتا ہے اور کہتا ہے کہ میں آپ کو یہ پے لوڈ بھیجنا چاہتا ہوں، اور آپ اس پر کارروائی کرتے ہیں۔ آپ یقیناً اپنے کندھوں کو جھکا سکتے ہیں اور ایسا کر سکتے ہیں، آپ کسی معاہدے پر آنے کی کوشش کر سکتے ہیں اور یہ بتا سکتے ہیں کہ ڈیٹا کو مطلوبہ فارمیٹ میں منتقل کرنا بہتر ہے۔ آئیے تصور کریں کہ ہم نے ایک ہوشیار کلائنٹ سے ملاقات کی اور اس بات پر اتفاق کیا کہ نمبروں کو عددی شکل میں منتقل کرنا بہتر ہے، اور چونکہ ہم پیسے کے بارے میں بات کر رہے ہیں، اس لیے اسے ڈبل ہونے دیں۔ ہمارے پے لوڈ کا اگلا پیرامیٹر ہائرنگ کی تاریخ ہو گی، کلائنٹ اسے متفقہ فارمیٹ میں بھیجے گا: yyyy-mm-dd، جہاں y سالوں کے لیے، m دنوں کے لیے، اور d دنوں کے لیے متوقع ہے - 2022- 08-12۔ اس وقت آخری فیلڈ کلائنٹ کو تفویض کردہ کاموں کی فہرست ہوگی۔ ظاہر ہے، ٹاسک ہمارے ڈیٹا بیس میں ایک اور ہستی ہے، لیکن ہم ابھی تک اس کے بارے میں زیادہ نہیں جانتے، اس لیے ہم سب سے بنیادی ہستی بنائیں گے جیسا کہ ہم نے پہلے ملازم کے ساتھ کیا تھا۔ صرف ایک چیز جو ہم اب فرض کر سکتے ہیں وہ یہ ہے کہ ایک ملازم کو ایک سے زیادہ کام تفویض کیے جاسکتے ہیں، اس لیے ہم نام نہاد ایک سے متعدد نقطہ نظر، ایک سے کئی تناسب کا اطلاق کریں گے۔ تفصیل سے بات کرتے ہوئے، ملازم کی میز میں ایک ریکارڈ ٹاسک ٹیبل کے کئی ریکارڈز سے مطابقت رکھتا ہے ۔ میں نے بھی ایک منفرد نمبر فیلڈ کے طور پر ایسی چیز کو شامل کرنے کا فیصلہ کیا، تاکہ ہم واضح طور پر ایک ملازم کو دوسرے سے ممتاز کر سکیں۔ اس وقت ہمارے ملازم کی کلاس اس طرح نظر آتی ہے:
@Entity
@Data
@Accessors(chain = true)
public class Employee {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @JsonIgnore
    Long id;

    @NotBlank
    @Column(unique = true)
    private String uniqueNumber;
    private String firstName;
    private String lastName;
    private String department;
    private Double salary;
    private LocalDate hired;

    @OneToMany
    @JoinColumn(name = "employee_id")
    List<Task> tasks = new ArrayList<>();
}
مندرجہ ذیل کلاس ٹاسک ہستی کے لیے بنائی گئی تھی۔
@Entity
@Data
@Accessors(chain = true)
public class Task {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long taskId;
}
جیسا کہ میں نے کہا، ہمیں ٹاسک میں کوئی نئی چیز نظر نہیں آئے گی، اس کلاس کے لیے ایک نیا ذخیرہ بھی بنایا گیا ہے، جو کہ ملازم کے لیے مخزن کی ایک نقل ہے - میں اسے نہیں دوں گا، آپ اسے تشبیہ سے خود بنا سکتے ہیں۔ لیکن ملازم طبقے کے بارے میں بات کرنا سمجھ میں آتا ہے۔ جیسا کہ میں نے کہا، ہم نے کئی شعبوں کو شامل کیا، لیکن اب صرف آخری میں دلچسپی ہے - کام۔ یہ ایک List<Task> tasks ہے ، اسے فوری طور پر ایک خالی ArrayList سے شروع کیا جاتا ہے اور کئی تشریحات کے ساتھ نشان زد کیا جاتا ہے۔ 1. @OneToMany جیسا کہ میں نے کہا، یہ ہمارے ملازمین کا کاموں کا تناسب ہوگا۔ 2. @JoinColumn - وہ کالم جس کے ذریعے اداروں کو جوائن کیا جائے گا۔ اس صورت میں، ٹاسک ٹیبل میں ایک ملازم_آئی ڈی کالم بنایا جائے گا جو ہمارے ملازم کی آئی ڈی کی طرف اشارہ کرے گا؛ یہ ہمارے لیے ForeighnKey کے طور پر کام کرے گا نام کی بظاہر تقدیس کے باوجود، آپ اپنی پسند کے مطابق کالم کا نام دے سکتے ہیں۔ صورت حال کچھ زیادہ پیچیدہ ہو جائے گی اگر آپ کو صرف ایک ID نہیں بلکہ کسی قسم کا اصلی کالم استعمال کرنے کی ضرورت ہے؛ ہم اس موضوع پر بعد میں بات کریں گے۔ 3. آپ نے آئی ڈی کے اوپر ایک نئی تشریح بھی دیکھی ہوگی - @JsonIgnore۔ چونکہ id ہماری داخلی ہستی ہے، اس لیے ضروری نہیں کہ ہم اسے کلائنٹ کو واپس کریں۔ 4. @NotBlank توثیق کے لیے ایک خاص تشریح ہے، جو کہتی ہے کہ فیلڈ کو null یا خالی سٹرنگ نہیں ہونا چاہیے 5. @Column(unique = true) کہتا ہے کہ اس کالم میں منفرد اقدار ہونی چاہئیں۔ لہذا، ہمارے پاس پہلے سے ہی دو ادارے ہیں، یہاں تک کہ وہ ایک دوسرے سے جڑے ہوئے ہیں۔ انہیں ہمارے پروگرام میں ضم کرنے کا وقت آگیا ہے - آئیے سروسز اور کنٹرولرز کے ساتھ ڈیل کریں۔ سب سے پہلے، آئیے getAllEmployees() طریقہ سے اپنے اسٹب کو ہٹا دیں اور اسے کسی ایسی چیز میں تبدیل کریں جو حقیقت میں کام کرے:
public List<Employee> getAllEmployees() {
       return employeeRepository.findAll();
   }
اس طرح، ہمارا ذخیرہ ہر وہ چیز جو ڈیٹابیس سے دستیاب ہے نکال کر ہمیں دے گا۔ یہ قابل ذکر ہے کہ یہ ٹاسک لسٹ بھی اٹھائے گا۔ لیکن اسے نکالنا یقیناً دلچسپ ہے، لیکن اگر وہاں کچھ نہیں ہے تو اسے نکالنا کیا ہے؟ یہ ٹھیک ہے، اس کا مطلب ہے کہ ہمیں یہ معلوم کرنے کی ضرورت ہے کہ وہاں کچھ کیسے رکھنا ہے۔ سب سے پہلے اپنے کنٹرولر میں ایک نیا طریقہ لکھتے ہیں۔
@PostMapping("${application.endpoint.employee}")
    public ResponseEntity<?> createOrUpdateEmployee(@RequestBody final Employee employee) {
        try {
            employeeService.save(employee);
        } catch (ValidationException e) {
            return ResponseEntity.badRequest().body(e.getViolations());
        }
        return ResponseEntity.status(HttpStatus.CREATED).build();
    }
یہ @PostMapping ہے، یعنی یہ ہمارے ملازمین کے اختتامی نقطہ پر آنے والی POST درخواستوں پر کارروائی کرتا ہے۔ عام طور پر، میں نے سوچا کہ چونکہ اس کنٹرولر کی تمام درخواستیں ایک اختتامی نقطہ پر آئیں گی، آئیے اسے تھوڑا سا آسان بنائیں۔ application.yml میں ہماری اچھی ترتیبات یاد رکھیں؟ آئیے ان کو ٹھیک کرتے ہیں۔ ایپلیکیشن سیکشن کو اب اس طرح نظر آنے دیں:
application:
  endpoint:
    root: api/v1
    employee: ${application.endpoint.root}/employees
    task: ${application.endpoint.root}/tasks
یہ ہمیں کیا دیتا ہے؟ حقیقت یہ ہے کہ کنٹرولر میں ہم ہر مخصوص طریقہ کے لیے میپنگ کو ہٹا سکتے ہیں، اور اختتامی نقطہ کو @RequestMapping("${application.endpoint.employee}") تشریح میں کلاس کی سطح پر سیٹ کیا جائے گا ۔ اب یہ خوبصورتی ہے۔ ہمارے کنٹرولر:
@RestController
@RequestMapping("${application.endpoint.employee}")
@RequiredArgsConstructor
public class EmployeeController {

    private final EmployeeService employeeService;

    @GetMapping
    public ResponseEntity<List<Employee>> getEmployees() {
        return ResponseEntity.ok().body(employeeService.getAllEmployees());
    }

    @PostMapping
    public ResponseEntity<?> createOrUpdateEmployee(@RequestBody final Employee employee) {
        try {
            employeeService.save(employee);
        } catch (ValidationException e) {
            return ResponseEntity.badRequest().body(e.getViolations());
        }
        return ResponseEntity.status(HttpStatus.CREATED).build();
    }
}
تاہم، آئیے آگے بڑھتے ہیں۔ CreateOrUpdateEmployee طریقہ میں بالکل کیا ہوتا ہے؟ ظاہر ہے، ہماری ملازم سروس کے پاس بچت کا ایک طریقہ ہے، جو بچت کے تمام کام کے لیے ذمہ دار ہونا چاہیے۔ یہ بھی واضح ہے کہ یہ طریقہ خود وضاحتی نام کے ساتھ استثناء پھینک سکتا ہے۔ وہ. کسی قسم کی توثیق کی جا رہی ہے۔ اور اس کا جواب براہ راست توثیق کے نتائج پر منحصر ہے، چاہے یہ 201 بنایا جائے گا یا 400 badRequest اس فہرست کے ساتھ جو غلط ہوا ہے۔ آگے دیکھتے ہوئے، یہ ہماری نئی توثیق کی خدمت ہے، یہ مطلوبہ فیلڈز کی موجودگی کے لیے آنے والے ڈیٹا کو چیک کرتی ہے (@NotBlank یاد رکھیں؟) اور فیصلہ کرتی ہے کہ آیا ایسی معلومات ہمارے لیے موزوں ہیں یا نہیں۔ بچت کے طریقہ کار پر جانے سے پہلے، آئیے اس سروس کی توثیق کریں اور اسے لاگو کریں۔ ایسا کرنے کے لیے، میں ایک علیحدہ توثیق پیکج بنانے کی تجویز پیش کرتا ہوں جس میں ہم اپنی سروس ڈالیں گے۔
import com.example.demo.exception.ValidationException;
import com.example.demo.persistence.entity.Employee;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Set;

import javax.validation.ConstraintViolation;
import javax.validation.Validator;

@Service
@RequiredArgsConstructor
public class ValidationService {

    private final Validator validator;

    public boolean isValidEmployee(Employee employee) throws ValidationException {
        Set<Constraintviolation<Employee>> constraintViolations = validator.validate(employee);

        if (CollectionUtils.isNotEmpty(constraintViolations)) {
            throw new ValidationException(buildViolationsList(constraintViolations));
        }
        return true;
    }

    private <T> List<Violation> buildViolationsList(Set<Constraintviolation<T>> constraintViolations) {
        return constraintViolations.stream()
                                   .map(violation -> new Violation(
                                                   violation.getPropertyPath().toString(),
                                                   violation.getMessage()
                                           )
                                   )
                                   .toList();
    }
}
کلاس بہت بڑی نکلی، لیکن گھبرائیں نہیں، ہم اب اس کا پتہ لگائیں گے :) یہاں ہم ریڈی میڈ توثیق لائبریری کے ٹولز استعمال کرتے ہیں javax.validation یہ لائبریری ہمارے پاس نئی انحصار سے آئی ہے۔ build.graddle نفاذ میں شامل کیا گیا 'org.springframework.boot:spring-boot-starter -validation' ہمارے پرانے دوست سروس اور RequiredArgsConstructor پہلے سے ہی ہمیں اس کلاس کے بارے میں جاننے کے لیے سب کچھ بتاتے ہیں، ایک پرائیویٹ فائنل ویلیڈیٹر فیلڈ بھی ہے۔ وہ جادو کرے گا۔ ہم نے isValidEmployee طریقہ بنایا ہے، جس میں ہم Employee entity کو پاس کر سکتے ہیں؛ یہ طریقہ ValidationException دیتا ہے، جسے ہم تھوڑی دیر بعد لکھیں گے۔ جی ہاں، یہ ہماری ضروریات کے لیے اپنی مرضی کی رعایت ہوگی۔ validator.validate(employee) طریقہ استعمال کرتے ہوئے، ہمیں ConstraintViolation اشیاء کی ایک فہرست ملے گی - وہ تمام عدم مطابقتیں جو ہم نے پہلے شامل کی ہیں توثیق کی تشریحات کے ساتھ۔ مزید منطق آسان ہے، اگر یہ فہرست خالی نہیں ہے (یعنی خلاف ورزیاں ہیں)، تو ہم ایک استثنا دیتے ہیں اور خلاف ورزیوں کی فہرست بناتے ہیں - buildViolationsList طریقہ برائے مہربانی نوٹ کریں کہ یہ ایک عام طریقہ ہے، یعنی مختلف اشیاء کی خلاف ورزیوں کی فہرستوں کے ساتھ کام کر سکتے ہیں - یہ مستقبل میں مفید ہو سکتا ہے اگر ہم کسی اور چیز کی توثیق کریں۔ یہ طریقہ اصل میں کیا کرتا ہے؟ اسٹریم API کا استعمال کرتے ہوئے، ہم خلاف ورزیوں کی فہرست سے گزرتے ہیں۔ ہم نقشہ کے طریقہ کار میں ہر خلاف ورزی کو اپنے خلاف ورزی آبجیکٹ میں تبدیل کرتے ہیں، اور نتیجے میں آنے والی تمام اشیاء کو ایک فہرست میں جمع کرتے ہیں۔ ہم اسے واپس کر رہے ہیں۔ آپ پوچھتے ہیں کہ ہمارا اپنا اعتراض اور کیا ہے؟ یہاں ایک سادہ ریکارڈ ہے۔
public record Violation(String property, String message) {}
جاوا میں ریکارڈز ایسی خاص اختراعات ہیں، اگر آپ کو ڈیٹا کے ساتھ کسی چیز کی ضرورت ہو، بغیر کسی منطق یا کسی اور چیز کے۔ اگرچہ میں خود ابھی تک یہ نہیں سمجھ سکا کہ ایسا کیوں کیا گیا، بعض اوقات یہ کافی آسان چیز ہوتی ہے۔ اسے باقاعدہ کلاس کی طرح علیحدہ فائل میں بنایا جانا چاہیے۔ اپنی مرضی کے مطابق ValidationException پر واپس جانا - ایسا لگتا ہے:
@RequiredArgsConstructor
public class ValidationException extends Exception {

    @Getter
    private final List<Violation> violations;
}
یہ تمام خلاف ورزیوں کی فہرست محفوظ کرتا ہے، لومبوک تشریح - گیٹر فہرست کے ساتھ منسلک ہے، اور ایک اور لومبوک تشریح کے ذریعے ہم نے مطلوبہ کنسٹرکٹر کو "نافذ کیا" :) یہاں یہ بات قابل غور ہے کہ میں isValid کے رویے کو بالکل درست طریقے سے نافذ نہیں کرتا ہوں۔ ... طریقہ، یہ یا تو صحیح یا استثناء واپس کرتا ہے، لیکن یہ خود کو معمول کے غلط تک محدود رکھنے کے قابل ہوگا۔ استثنائی نقطہ نظر اس لئے بنایا گیا ہے کہ میں اس غلطی کو کلائنٹ کو واپس کرنا چاہتا ہوں، جس کا مطلب ہے کہ مجھے بولین طریقہ سے صحیح یا غلط کے علاوہ کچھ اور واپس کرنے کی ضرورت ہے۔ خالصتاً داخلی توثیق کے طریقوں کی صورت میں، استثناء دینے کی ضرورت نہیں ہے؛ یہاں لاگنگ کی ضرورت ہوگی۔ تاہم، آئیے اپنی EmployeeService پر واپس آتے ہیں، ہمیں اب بھی اشیاء کو محفوظ کرنا شروع کرنا ہے :) آئیے دیکھتے ہیں کہ یہ کلاس اب کیسی دکھتی ہے:
@Service
@RequiredArgsConstructor
public class EmployeeService {

    private final EmployeeRepository employeeRepository;
    private final ValidationService validationService;

    public List<Employee> getAllEmployees() {
        return employeeRepository.findAll();
    }

    @Transactional
    public void save(Employee employee) throws ValidationException {
        if (validationService.isValidEmployee(employee)) {
            Employee existingEmployee = employeeRepository.findByUniqueNumber(employee.getUniqueNumber());
            if (existingEmployee == null) {
                employeeRepository.save(employee);
            } else {
                existingEmployee = updateFields(existingEmployee, employee);
                employeeRepository.save(existingEmployee);
            }
        }
    }

    private Employee updateFields(Employee existingEmployee, Employee updatedEmployee) {
        return existingEmployee.setDepartment(updatedEmployee.getDepartment())
                               .setSalary(updatedEmployee.getSalary())
            				 //TODO implement tasks merging instead of replacement
                               .setTasks(updatedEmployee.getTasks());
    }
}
نئی حتمی پراپرٹی پرائیویٹ فائنل ValidationService validationService دیکھیں۔ محفوظ کرنے کا طریقہ خود ہی @Transactional تشریح کے ساتھ نشان زد ہوتا ہے تاکہ اگر RuntimeException موصول ہوتا ہے تو تبدیلیاں واپس کر دی جاتی ہیں۔ سب سے پہلے، ہم اس سروس کا استعمال کرتے ہوئے آنے والے ڈیٹا کی توثیق کرتے ہیں جو ہم نے ابھی لکھی ہے۔ اگر سب کچھ ٹھیک ہو گیا، تو ہم چیک کرتے ہیں کہ آیا ڈیٹا بیس میں کوئی موجودہ ملازم موجود ہے (ایک منفرد نمبر کا استعمال کرتے ہوئے)۔ اگر نہیں، تو ہم نیا محفوظ کرتے ہیں، اگر کوئی ہے تو، ہم کلاس میں فیلڈز کو اپ ڈیٹ کرتے ہیں۔ اوہ ہاں، ہم اصل میں کیسے چیک کرتے ہیں؟ ہاں، یہ بہت آسان ہے، ہم نے ایمپلائی ریپوزٹری میں ایک نیا طریقہ شامل کیا ہے:
public interface EmployeeRepository extends JpaRepository<Employee, Long> {
    Employee findByUniqueNumber(String uniqueNumber);
}
کیا قابل ذکر ہے؟ میں نے کوئی منطق یا SQL استفسار نہیں لکھا، حالانکہ وہ یہاں دستیاب ہے۔ بہار، صرف طریقہ کا نام پڑھ کر، اس بات کا تعین کرتا ہے کہ میں کیا چاہتا ہوں - ByUniqueNumber تلاش کریں اور متعلقہ سٹرنگ کو طریقہ میں منتقل کریں۔ فیلڈز کو اپ ڈیٹ کرنے کی طرف لوٹنا - یہاں میں نے عقل استعمال کرنے کا فیصلہ کیا اور صرف محکمہ، تنخواہ اور کاموں کو اپ ڈیٹ کرنے کا فیصلہ کیا، کیونکہ نام تبدیل کرنا، اگرچہ ایک قابل قبول چیز ہے، پھر بھی بہت عام نہیں ہے۔ اور ملازمت کی تاریخ کو تبدیل کرنا عام طور پر ایک متنازعہ مسئلہ ہے۔ یہاں کیا کرنا اچھا ہو گا؟ کام کی فہرستوں کو یکجا کریں، لیکن چونکہ ہمارے پاس ابھی تک کام نہیں ہیں اور ان میں فرق کرنا نہیں جانتے ہیں، اس لیے ہم TODO کو چھوڑ دیں گے۔ آئیے اپنے فرینکنسٹین کو شروع کرنے کی کوشش کریں۔ اگر میں کچھ بیان کرنا نہیں بھولتا ہوں، تو یہ کام کرے گا، لیکن سب سے پہلے، یہاں کلاس ٹری ہے جو ہمیں ملا ہے: جن کلاسوں میں REST API اور ڈیٹا کی توثیق - 1 ترمیم کی گئی ہے ان کو نیلے رنگ میں ہائی لائٹ کیا گیا ہے، نئی کو سبز رنگ میں ہائی لائٹ کیا گیا ہے، اگر آپ کام کرتے ہیں تو ایسے اشارے مل سکتے ہیں۔ گٹ ریپوزٹری کے ساتھ، لیکن گٹ ہمارے مضمون کا موضوع نہیں ہے، لہذا ہم اس پر غور نہیں کریں گے۔ لہذا، اس وقت ہمارے پاس ایک اختتامی نقطہ ہے جو دو طریقوں GET اور POST کو سپورٹ کرتا ہے۔ ویسے، اختتامی نقطہ کے بارے میں کچھ دلچسپ معلومات. مثال کے طور پر، ہم نے GET اور POST کے لیے الگ الگ اینڈ پوائنٹس کیوں مختص نہیں کیے، جیسے getAllEmployees یا createEmployees؟ سب کچھ انتہائی آسان ہے - تمام درخواستوں کے لیے ایک نقطہ کا ہونا بہت زیادہ آسان ہے۔ روٹنگ HTTP طریقہ کی بنیاد پر ہوتی ہے اور یہ بدیہی ہے، getAllEmployees، getEmployeeByName، get... اپ ڈیٹ... تخلیق کریں... حذف کریں... کے تمام تغیرات کو یاد رکھنے کی ضرورت نہیں ہے، آئیے جانچتے ہیں کہ ہمیں کیا ملا ہے۔ میں نے پچھلے مضمون میں پہلے ہی لکھا تھا کہ ہمیں پوسٹ مین کی ضرورت ہوگی، اور اسے انسٹال کرنے کا وقت آگیا ہے۔ پروگرام انٹرفیس میں، ہم ایک نئی POST درخواست بناتے ہیں REST API اور ڈیٹا کی توثیق - 2 اور اسے بھیجنے کی کوشش کرتے ہیں۔ اگر سب کچھ ٹھیک رہا تو ہمیں اسکرین کے دائیں جانب اسٹیٹس 201 ملے گا۔ لیکن مثال کے طور پر، ایک ہی چیز بھیجنے کے بعد لیکن ایک منفرد نمبر کے بغیر (جس پر ہمارے پاس توثیق ہے)، مجھے ایک مختلف جواب ملتا ہے: REST API اور ڈیٹا کی توثیق - 3 ٹھیک ہے، آئیے چیک کریں کہ ہمارا مکمل انتخاب کیسے کام کرتا ہے - ہم اسی اختتامی نقطہ کے لیے ایک GET طریقہ بناتے ہیں اور اسے بھیجتے ہیں۔ . REST API اور ڈیٹا کی توثیق - 4 مجھے پوری امید ہے کہ سب کچھ آپ کے لیے بالکل اسی طرح کام کرے گا جیسا کہ اس نے میرے لیے کیا تھا، اور اگلے مضمون میں آپ سے ملیں گے ۔
تبصرے
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION