Prije nekoliko godina objavio sam blog post o prikazu podataka API-ja Sudskog registra – pravosudje.hr.
API se tada nalazio na adresi https://sudreg-api.pravosudje.hr, dok će se od 1. travnja nalaziti na adresi https://sudreg-data.gov.hr/.
Više o detaljima i razlozima prebacivanja API-ja na novu adresu možete saznati na https://data.gov.hr/ckan/dataset/sudski-registar.
Ukratko, to znači da se osim URL-a putem kojega će se pozivati API mijenjaju i parametri potrebni za pristup tim podacima.
“Portal otvorenih podataka Sudskog registra namijenjen je razvojnim inženjerima koji u svoja aplikativna rješenja žele preuzimati podatke Sudskog registra (https://sudreg.pravosudje.hr) u strojno čitljivom obliku.
Za pristup podacima potrebno je napraviti registraciju. Nakon uspješno predanog registracijskog obrasca korisnik će dobiti e-mail za potvrdu svog korisničkog računa. Verifikacijom računa korisnik će biti preusmjeren na stranice aplikacije te će mu se dodijeliti Client ID, Client Secret i link za dohvat tokena koji omogućuju pristup RESTapi sučeljima.”
Registracija i aktivacija
Prije registracije potrebno je prijaviti se, a to je moguća napraviti korištenjem e-građana te putem servisa Facebook, Google i Microsoft na linku https://data.gov.hr/ckan/dataset/sudski-registar i klikom na ‘Prijava’ u gornjem desnom kutu ekrana.
Nakon prijave mogu se vidjeti detalji o postupku registracije i što se njome dobije. Klikom na “Registracija” pokreće se postupak.
Klikom na “Registracija” otvara se jednostavna forma gdje se navodi naziv i opis projekta u kojemu će se koristiti API.
Klikom na “Predaj zahtjev” otvara se sljedeći ekran gdje se vide detalji poput parametara Client Id i Client Secret koji će biti potrebni za slanje upita na API tj. dobivanje tokena.
Prije nego se prikazani podaci mogu koristiti potrebno je potvrditi tj. verificirati e-mail klikom na “Potvrdi”.
Nakon toga preostaje još kliknuti na “Aktivacija” i to je to što se registracije tiče.
I konačno, podaci su spremni za korištenje.
Provjera rada API-ja
Kako je i navedeno u dokumentaciji API mogu provjeriti koristeći Curl (Client for URL) naredbu i to želim napraviti prije nego krenem s postavljanjem Angular forme.
Naredba se upisuje u naredbeni redak (CMD) u sljedećem obliku: curl -i -k --user ClientId:ClientSecret --data "grant_type=client_credentials" https://sudreg-data.gov.hr/api/oauth/token
Iz navedenog mogu vidjeti u kojem obliku i koje parametre će mi API vratiti. U ovom slučaju najvažniji mi je parametar access_token koji će mi trebati prilikom pozivanja drugih API-ja.
Također vidim da token vrijedi 6 sati (21600 sekundi) od trenutka kreiranja.
Dohvaćanje tokena testirat ću i koristeći Postman.
Odmah ću, također putem Curl naredbe, isprobati jedan API u kojem ću proslijediti access_token da bi dobio podatke. Želim se uvjeriti da sve radi prije nego počnem s kreiranjem API servisa u Angularu.
Pokretanjem Curl naredbe curl --location "https://sudreg-data.gov.hr/api/javni/sudovi?expand_relations=true" ^ --header "Content-Type: application/json" ^ --header "Authorization: Bearer access_token" dobijem sljedeće:
Kako se može vidjeti iz gornje naredbe ovdje prosljeđujem samo dva parametara u headeru i već sam dobio “osjećaj” kako će funkcionirati svi ostali API pozivi.
Nadam se bez grešaka koje neki od njih trenutno imaju. 🙂
API detalji_subjekta
S obzirom da me API detalji_subjekta trenutno najviše zanima više ću pažnje obratiti na njega što se tiče dokumentacije.
Na adresi https://sudreg-data.gov.hr/api/OpenAPIs/OpenAPIJavni se nalaze sve dostupne API točke. Između ostalog tu je i detalji_subjekta.
Iz dokumentacije vidim da se radi o get metodi i koje obavezne parametre trebam slati.
Kreiranje API servisa
U servisu će se nalaziti dvije funkcije. Jedna će dohvaćati access_token, a druga podatke o tvrtki prema OIB-u ili MBS-u.
Obavezni parametri za dobivanje tokena:
- Content-Type (string) / header – ‘application/x-www-form-urlencoded’
- Authorization (string) / header – ‘Basic ‘ + btoa(‘ClientId:ClientSecret’)
- grant_type (string) / body – client_credentials
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 |
import { Injectable } from '@angular/core'; import { HttpClient, HttpHeaders } from '@angular/common/http'; import { map } from 'rxjs/operators'; @Injectable({ providedIn: 'root' }) export class ApiService { sudregURL: string = "https://sudreg-data.gov.hr/api/"; constructor( private _http: HttpClient ){} getToken(){ const headers = new HttpHeaders({ 'Content-Type': 'application/x-www-form-urlencoded', 'Authorization': 'Basic ' + btoa('ClientId:ClientSecret') }); const body = new URLSearchParams(); body.set('grant_type', 'client_credentials'); return this._http.post(this.sudregURL + 'oauth/token', body.toString(), { headers }); } detaljiSubjekta(access_token: string, tip_identifikatora: string, identifikator: string){ const headers = new HttpHeaders({ 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + access_token }); return this._http.get(this.sudregURL + 'javni/detalji_subjekta?expand_relations=true&tip_identifikatora='+tip_identifikatora+'&identifikator='+identifikator, { headers }) .pipe(map((res: any) => res )); } } |
Obavezni parametri za dohvaćanje detalja tvrtke:
- Content-Type (string) / header – ‘application/json’
- Authorization (string) / header – ‘Bearer ‘ + access_token
- tip_identifikatora (string) / query – ‘oib’ ili ‘mbo’
- identifikator (string) / query – 0000000000 ili 000000000
Angular forma
Forma će biti jednostavna. Nakon unosa OIB-a ili MBS-a popunit će se polja naziv, adresa i grad. API naravno dohvaća puno više od toga.
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 |
<div class="page-content"> <form class="modal-content" id="angularForma" [formGroup]="angularForma"> <div class="modal-header p-4"> <h5 class="modal-title">Provjera poslovnog subjekta</h5> </div> <div class="modal-body p-4"> <div class="form-group row"> <div class="col-sm-6"> <label for="oib">OIB:</label> <input class="form-control form-control-line" id="oib" type="text" pattern="[-+]?[0-9]*[.,]?[0-9]+" minlength="11" maxlength="11" formControlName="oib" (keyup)="dohvatiDetalje(angularForma)"> </div> <div class="col-sm-6"> <label for="mbs">MBS:</label> <input class="form-control form-control-line" id="mbs" type="text" pattern="[-+]?[0-9]*[.,]?[0-9]+" minlength="9" maxlength="9" formControlName="mbs" (keyup)="dohvatiDetalje(angularForma)"> </div> </div> <div class="form-group"> <label for="naziv">Naziv:</label> <input class="form-control form-control-line" id="naziv" type="text" formControlName="nazivtvrtke"> </div> <div class="form-group"> <label for="adresa">Adresa:</label> <input class="form-control form-control-line" id="adresa" type="text" formControlName="ulica"> </div> <div class="form-group"> <label for="grad">Grad:</label> <input class="form-control form-control-line" id="grad" type="text" formControlName="grad"> </div> </div> </form> </div> |
Što se funkcionalnosti tiče i s obzirom da je ovo samo demo prikaz neću ići previše u detalje.
Unutar ngOnInit() funkcije pozivam API za dohvaćanje tokena. U produkcijskom okruženju ne bih to radio na ovaj način nego bih spremio token i novi ne bih tražio sljedećih 6 sati dok trenutni ne istekne.
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 |
import { Component, OnInit } from '@angular/core'; import { FormBuilder, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms'; import { RouterOutlet } from '@angular/router'; import { ApiService } from './api.service'; import { CommonModule } from '@angular/common'; import { FormControl } from '@angular/forms'; @Component({ selector: 'app-root', standalone: true, imports: [CommonModule, RouterOutlet, ReactiveFormsModule], templateUrl: './app.component.html', styleUrl: './app.component.scss' }) export class AppComponent implements OnInit { angularForma!: FormGroup; title = 'API - Sudreg'; access_token: string = ''; constructor( private _fb: FormBuilder, private _apiService: ApiService ){ 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: new FormControl({ value: '', disabled: true }), ulica: new FormControl({ value: '', disabled: true }), grad: new FormControl({ value: '', disabled: true }) }); } ngOnInit(){ this._apiService.getToken().subscribe((res: any) => { this.access_token = res.access_token; }); } dohvatiDetalje(angularForma: FormGroup){ if(angularForma.value.oib && angularForma.value.oib.length == 11){ console.log("Dohvaćam detalje..."); this._apiService.detaljiSubjekta(this.access_token, 'oib', angularForma.value.oib).subscribe(res => { console.log("Detalji tvrtke:"); console.log(res); if(res){ this.angularForma = this._fb.group({ oib: res.oib, mbs: res.mbs, nazivtvrtke: res.skracena_tvrtka['ime'], ulica: res.sjediste['ulica'] + ' ' + res.sjediste['kucni_broj'] + (res.sjediste['kucni_podbroj'] ? (res.sjediste['kucni_podbroj']) : ''), grad: res.sjediste['naziv_naselja'] }); } else { alert("Neuspješno dohvaćanje podataka prema OIB-u!"); this.angularForma.controls['oib'].setValue(null); } }); } else if (angularForma.value.mbs && angularForma.value.mbs.length == 9){ this._apiService.detaljiSubjekta(this.access_token, 'mbs', angularForma.value.mbs).subscribe(res => { if(res){ this.angularForma = this._fb.group({ oib: res.oib, mbs: res.mbs, nazivtvrtke: res.skracena_tvrtka[0].ime, ulica: res.sjediste['ulica'] + ' ' + res.sjediste['kucni_broj'] + (res.sjediste['kucni_podbroj'] ? (res.sjediste['kucni_podbroj']) : ''), grad: res.sjediste['naziv_naselja'] }); } else { alert("Neuspješno dohvaćanje podataka prema MBS-u!"); this.angularForma.controls['mbs'].setValue(null); } }); } } } |
U praksi to izgleda ovako. Unosom OIB-a ili MBS-a poziva se funkcija za dohvaćanje detalja poslovnog subjekta.
Jednom kada access_token istekne dobit će se poruka
I to je to. Istovremeno vrlo jednostavan i vrlo koristan API koji može poboljšati funkcionalnosti nekog programskog rješenja.