OBAVIJEST! API Sudskog registra se od 1. travnja prebacuje na novu adresu. Više o tome u blog postu Dohvaćanje podataka s API-ja Sudskog registra data.gov.hr
U ovom ću blog postu pokazati kako napraviti upit na API Sudskog registra i dohvatiti informacije o poslovnom subjektu prema OIB-u/MBS-a. U dokumentaciji se može vidjeti koje je sve informacije i preko kojih ruta moguće napraviti, ali ja ću se zadržati na onoj po meni najzanimljivijoj subjekt_detalji_Get.
Projekt je dostupan na GitHubu.
Uvod
Za kreiranje forme koristiti ću FormBuilder, a mogao sam isto tako koristiti i ngModel ili FormControl. Više o tome objavio sam u jednom od prijašnjih blog postova. Forma će se sastojati od nekoliko polja od kojih će većina biti obavezna. Prilikom unosa OIB-a ili MBS-a odmah ide provjera na API Sudskog registra i tek nakon te provjere moguće je kliknuti na gumb “Spremi” nakon kojega se podaci mogu spremiti u bazu podataka.
Provjera rada API-ja
Prije nego krenem s izradom Angular forme idem se uvjeriti da API radi na način kako je prikazano u dokumentaciji i da mi vraća podatke koje želim koristiti. API je moguće testirati i na ovoj adresi. Da nema te forme koristio bi Postman.
URL na koji radim upit je:
1 |
https://sudreg-api.pravosudje.hr/javni/subjekt_detalji?tipIdentifikatora={tipIdentifikatora}&identifikator={identifikator}[&expand_relations][×tamp_id] |
Obavezni parametri upita su sljedeći:
- tipIdentifikatora* (string) – moguće koristiti oib (osobni identifikacijski broj) ili mbs (matični broj subjekta)
- identifikator* (integer) – oib ili mbs koristim u obliku broja (int64)
- Ocp-Apim-Subscription-Key* (string) – ide u header, a dobije se nakon registracije
Kreiranje API servisa
U servisu će se nalaziti dvije funkcije. Jedna će dohvaćati podatke prema OIB-u, a druga prema MBS-a.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
import { Injectable } from '@angular/core'; import { HttpClient, HttpHeaders } from '@angular/common/http'; import { map } from 'rxjs/operators'; @Injectable({ providedIn: 'root' }) export class ApiService { httpOptions = { headers: new HttpHeaders({ 'Ocp-Apim-Subscription-Key': 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' }) }; constructor(private _http: HttpClient) { } sudskiRegistarOIB(oib:any) { return this._http.get('https://sudreg-api.pravosudje.hr/javni/subjekt_detalji?tipIdentifikatora=oib&identifikator='+oib+'&expand_relations=true', this.httpOptions) .pipe(map((res: any) => res )); } sudskiRegistarMBS(mbs:any) { return this._http.get('https://sudreg-api.pravosudje.hr/javni/subjekt_detalji?tipIdentifikatora=mbs&identifikator='+mbs+'&expand_relations=true', this.httpOptions) .pipe(map((res: any) => res )); } } |
HTML forma
Kreiram formu sa poljima:
–
oib – dužina 11 znakova. Obavezno polje.
–
mbs – dužina 9 znakova. Obavezno polje.
–
nazivtvrtke – Obavezno polje.
–
ulica – Obavezno polje.
–
grad – Obavezno polje.
–
e-mail
Prilikom unosa OIB-a ili MBS-a odmah se vrši provjera na API putem funkcije provjera(angularForma). Tek nakon što se forma ispuni podacima tj. kada se zadovolji unos obaveznih polja moguće je kliknuti na gumb “Spremi”.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
<form class="form-content" id="angularForma" [formGroup]="angularForma" (ngSubmit)="spremi()"> <div class="form-header"> <h5 class="title">Unos poslovnog subjekta</h5> </div> <div class="form-body"> <div class="form-group row"> <div class="col-sm-6"> <input class="form-control form-control-line" type="text" pattern="[0-9]{11}" minlength="11" maxlength="11" formControlName="oib" placeholder="OIB" (keyup)="provjera(angularForma)"> </div> <div class="col-sm-6"> <input class="form-control form-control-line" type="text" pattern="[-+]?[0-9]*[.,]?[0-9]+" minlength="9" maxlength="9" formControlName="mbs" placeholder="MBS" (keyup)="provjera(angularForma)"> </div> </div> <div class="form-group"> <input class="form-control form-control-line" type="text" formControlName="nazivtvrtke" placeholder="Naziv"> </div> <div class="form-group"> <input class="form-control form-control-line" type="text" formControlName="ulica" placeholder="Adresa"> </div> <div class="form-group"> <input class="form-control form-control-line" type="text" formControlName="grad" placeholder="Grad"> </div> <div class="form-group"> <input class="form-control form-control-line" type="email" formControlName="email" pattern="^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$" placeholder="E-mail"> </div> </div> <div class="form-footer justify-content-between"> <div class="text-center"> <button class="btn btn-primary btn-rounded" [disabled]="!angularForma.valid" type="submit">Spremi</button> </div> </div> </form> |
Funkcionalnost forme
Unutar ngOnInit() funkcije radim inicijalizaciju forme. Ovdje odmah dodajem i Validators kako bi mogao validirati potrebna polja i spriječiti klik na gumb “Spremi” pomoću [disabled]="!angularForma.valid" u slučaju kada forma nije ispravno ispunjena.
Kada se unutar polja forme unesu OIB ili MBS poziva se funkcija provjera(angularForma). Prvo vršim provjeru koja vrsta identifikatora (OIB ili MBS) je unesena jer ću kasnije na osnovu toga pozivati pripadajući API Sudskog registra iz ApiService i paralelno provjeravam da su ispravne dužine. Nakon toga provjeravam da unutar unesenih znakova nema slova tj. da su samo brojevi match(/^[0-9]+$/). Kada su svi navedeni uvjeti zadovoljeni pozivam this._apiService.sudskiRegistarOIB ili this._apiService.sudskiRegistarMBS te prikazujem dobivene podatke console.log(res) i odmah popunjavam formu.
Kada je forma ispravno validirana podaci će se uspješno dohvatiti.
Ne međutim, ostaje problem kod popunjavanja forme sa nasumičnim brojevima koji će ispravno biti validirani prema dužini iako ne postoje u Registru. Npr. netko za OIB može unijeti 11 nula ili za MBS 9 nula i forma će biti validna te će se taj poslovni subjekt moći spremiti u bazu podatka.
To mogu spriječiti koristeći setValue ili patchValue. Znači, ako mi API Sudskog registra ne vrati podatke neću dopustiti da forma prođe kao validna i da se uopće može kliknuti na “Spremi”.
–
this.angularForma.controls['oib'].setValue(null);
–
this.angularForma.controls['oib'].patchValue(null);
Što se adrese tiče stavio sam uvjet da se prikaže ispravna vrijednost neovisno o tome ima li prikazana adresa uz broj i podbroj tj. slovo (res.sjedista[0].kucni_podbroj ? (res.sjedista[0].kucni_podbroj) : '') .
Npr. u adresi Dragutina Žanića Karle 27a je ‘a’ podbroj .
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
import { Component, OnInit } from '@angular/core'; import { FormGroup, FormBuilder, Validators } from '@angular/forms'; import { ApiService } from './api.service'; import * as toastr from 'toastr'; @Component({ selector: 'app-angular-forma', templateUrl: './angular-forma.component.html', styleUrls: ['./angular-forma.component.css'], providers: [ApiService] }) export class AngularFormaComponent implements OnInit { angularForma: FormGroup; constructor(private _fb: FormBuilder, private _apiService: ApiService) { } ngOnInit() { //Inicijalizacija forme this.angularForma = this._fb.group({ oib: ['', [Validators.required, Validators.minLength(11), Validators.maxLength(11), Validators.pattern('[-+]?[0-9]*[.,]?[0-9]+')]], mbs: ['', [Validators.required, Validators.minLength(9), Validators.maxLength(9), Validators.pattern('[-+]?[0-9]*[.,]?[0-9]+')]], nazivtvrtke: ['', Validators.required], ulica: ['', Validators.required], grad: ['', Validators.required], email: ['', Validators.email] }); } provjera(angularForma){ //OIB if(angularForma.value.oib && angularForma.value.oib.length == 11){ if(angularForma.value.oib.match(/^[0-9]+$/)){ this._apiService.sudskiRegistarOIB(angularForma.value.oib).subscribe(res => { console.log(res); if(res){ this.angularForma = this._fb.group({ oib: res.oib, mbs: res.mbs, nazivtvrtke: res.skracene_tvrtke[0].ime, ulica: res.sjedista[0].ulica + ' ' + res.sjedista[0].kucni_broj + (res.sjedista[0].kucni_podbroj ? (res.sjedista[0].kucni_podbroj) : ''), grad: res.sjedista[0].naziv_naselja, email: '' }); } else { toastr.error("Neuspješno dohvaćanje podataka prema OIB!"); this.angularForma.controls['oib'].setValue(null); } }); } else { toastr.error("OIB mora biti u obliku broja!"); } //MBS } else if(angularForma.value.mbs && angularForma.value.mbs.length == 9){ if(angularForma.value.mbs.match(/^[0-9]+$/)){ this._apiService.sudskiRegistarMBS(angularForma.value.mbs).subscribe(res => { console.log(res); if(res){ this.angularForma = this._fb.group({ oib: res.oib, mbs: res.mbs, nazivtvrtke: res.skracene_tvrtke[0].ime, ulica: res.sjedista[0].ulica + ' ' + res.sjedista[0].kucni_broj + (res.sjedista[0].kucni_podbroj ? (res.sjedista[0].kucni_podbroj) : ''), grad: res.sjedista[0].naziv_naselja, email: '' }); } else { toastr.error("Neuspješno dohvaćanje podataka prema MBS!"); this.angularForma.controls['mbs'].setValue(null); } }); } else { toastr.error("MBS mora biti u obliku broja!"); } } else { // } } spremi(){ console.log(this.angularForma); } } |
Jako dobro!
Mislim da bi šira javnost trebala razumijeti i “hidden” priču iza ove – Ministarstvo pravosuđa je otvorilo API Sudskog registra već odavno, samo se malo zna to tome. Odličan pristup i za pohvaliti – što mislite koliko bi nam bio jednostavniji život kada bi ovo bio programatski korak državne uprave koja podatke objavljuje na nekom Government Bus-u ili API Marketplaceu?
Kao da nisu tijelo naše vlasti 😉. Ratko, odlicna ideja…
NIje ideja, znam da kolege iz APIS-IT rade na nečem sličnom. Samo da se GSB još otvori i prema vanjskom svijetu…
Super. Pristup Poreznoj (EDIP – dohodak i primitak) je uspješno riješen. Pristup MUP-u (boravište i vlasništva vozila, također). Dugovanja tvrtki? Pristup registru udruga? ima toga još, ali apsolutno podržavam jedan JEDINSTVENI API prema državnim evidencijama, bio bi daleko jednostavniji. Samo naprijed…
Najbliže tome što trenutno vidim je pristup skupovima podataka na https://data.gov.hr/data/ putem CKAN API-ja.
Ako sam sudski ne gonjen da li smijem radit u državnoj tvrtkci???
Stavovi i mišljenja na ovom postu moji su osobni stavovi i ne odražavaju stavove mojih poslovnih partnera i tvrtki u kojima radim ili s kojima surađujem.
Kako iz registra dobiti i poštanski broj sjedišta tvrtke uz ime naselja.
Nažalost čini se da API taj podatak ne vraća.
Koliko dugo ste čekali API key? Već deset dana čekam da mi se odobri pristup.
Davno je to bilo, ali koliko se sjećam isti dan sam sve dobio i krenuo raditi demo aplikaciju.
Da, izgleda da je prije bilo jednsotavnije. Sad se zatraži “subscription” za API servis i onda to tako stoji danima – nikako da se odobri. Nema na stranici ni jedan kontakt/mail/telefon.
“You have successfully submitted a subscription request to the Javni korisnici product. You will be notified when the request is approved”
Možda da probaš ovdje https://data.gov.hr/ckan/dataset/sudski-registar. Koliko vidim nude isti set podataka.
Uspio sam s tom verzijom. Zahvaljujem 🙂